I'm now working on making the front end look pretty.
The Problem
One of the things I wanted to do was change the colour of the chatbot's title in the text widget to make it easier to read. I thought it would be pretty easy.
My guess was that I could modify the colour from the .insert method. A little like this:
Fail!!!text.insert(END,'Bottity Bottity Bot Bot: '+ BotInput + '\n',foreground='red')
Life isn't that easy.
The Solution
It turns out that it is quite a task to add a colour to words in a text widget in Tkinter. The best hack I could find was to modify a search and highlight function I found in Python in a Nutshell by Alex Martelli.
I had to make some changes which basically removed the search function and replaced it with a key word of the name of my chatbot, in this case: Bottity Bottity Bot Bot
Here are the results in a simple example:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
###Changing the colour of selected text in Tkinter Text wiget### | |
from tkinter import * | |
from tkinter import ttk | |
root = Tk( ) | |
# fill rest of root with a Text and put some text there | |
BotInput = "This usually links to a database dictionary of responses." | |
###This is were the magic happens### | |
# action-function for the Button: highlight all occurrences of string | |
def find( ): | |
# get string to look for (if empty, no searching) | |
s = "Bottity Bottity Bot Bot:" | |
if s: | |
# start from the beginning (and when we come to the end, stop) | |
idx = '1.0' | |
while 1: | |
# find next occurrence, exit loop if no more | |
idx = text.search(s, idx, nocase=1, stopindex=END) | |
if not idx: break | |
# index right after the end of the occurrence | |
lastidx = '%s+%dc' % (idx, len(s)) | |
# tag the whole occurrence (start included, stop excluded) | |
text.tag_add('found', idx, lastidx) | |
# prepare to search for next occurrence | |
idx = lastidx | |
# use a red foreground for all the tagged occurrences | |
text.tag_config('found', foreground='red') | |
# This displays the entries from the Bot and the User in the text | |
def display_entry(*args): | |
UserInput = Comment.get() | |
text.insert(END, | |
'Bottity Bottity Bot Bot: '+ BotInput + '\n') | |
text.insert(END, | |
'User: ' +UserInput +'\n') | |
Comment.delete(0,END) | |
#Runs the function | |
find() | |
#Creat text wiget | |
text = Text(root) | |
text.pack() | |
#Entry field to add content to text wiget. | |
Comment_Lbl = ttk.Label(root, text="Comment here:") | |
Comment_Lbl.pack() | |
Comment = ttk.Entry(root) | |
Comment.pack() | |
Comment.bind("<Return>", display_entry) | |
Comment.focus() | |
Comment_Button = ttk.Button(root, text="Enter", command = lambda:display_entry(None)) | |
Comment_Button.pack() | |
root.mainloop( ) | |
P.S. I really like the lastidx = '%s+%dc' % (idx, len(s)) variable. This was such a clever bit of code that I spent an hour down the rabbit hole on String Formatting Operations.
No comments:
Post a Comment