Reputation: 2094
I would like to know how (If Possible) to listen to a certain phrase or word that is entered in a text box and the run a command.
For instance if i type the phrase "turn me red" i would like to know if it is possible to turn it red without pressing enter.
I just started and here is what i have:
from Tkinter import *
class mywidgets:
def __init__(self,root):
frame=Frame(root)
frame.pack()
self.txtfr(frame)
return
def txtfr(self,frame):
#define a new frame and put a text area in it
textfr=Frame(frame)
self.text=Text(textfr,height=10,width=50,background='white')
# put a scroll bar in the frame
scroll=Scrollbar(textfr)
self.text.configure(yscrollcommand=scroll.set)
#pack everything
self.text.pack(side=LEFT)
scroll.pack(side=RIGHT,fill=Y)
textfr.pack(side=TOP)
return
def main():
root = Tk()
s=mywidgets(root)
root.title('textarea')
root.mainloop()
main()
Upvotes: 5
Views: 5737
Reputation: 70088
So i thought it would be a little cleaner if rather than edit your code, i just provided a fresh example of working code that exhibits the behavior you are interested in.
Here's what the code below does: when you run it, you get a little widget with an empty text box (technically, a Label in Tkinter) for the user to supply some value. When they enter a numeric value (integer or float) and then click the Calculate button then equivalent value in meters appears just below. If however, the user keys in 'red' then the word 'blue' appears as soon as it is entered--i.e., Blue will appear even though the Calculate button nor anything else was clicked.
As you can see in the penultimate line below, getting the behavior you want is just a matter of describing the behavior you want in the Tkinter event syntax.
from Tkinter import *
import ttk
root = Tk()
def calculate(*args) :
value = float(feet.get())
meters.set((0.305 * value * 10000. + .5)/10000.)
def callback_function(*args) :
meters.set('blue')
mf = ttk.Frame(root, padding="3 3 12 12")
mf.grid(column=0, row=0, sticky=(N, W, E, S))
mf.columnconfigure(0, weight=1)
mf.rowconfigure(0, weight=1)
feet = StringVar()
meters = StringVar()
feet_entry = ttk.Entry(mf, width=7, textvariable=feet)
feet_entry.grid(column=2, row=1, sticky=(W, E))
ttk.Label(mf, textvariable=meters, background='#E9D66B').grid(column=2,
row=2, sticky=(W, E))
ttk.Button(mf, text="Calculate", command=calculate).grid(column=2,row=3,
sticky=W)
ttk.Label(mf, text="feet").grid(column=3, row=1, sticky=W)
ttk.Label(mf, text="is equivalent to").grid(column=1, row=2, sticky=E)
ttk.Label(mf, text="meters").grid(column=3, row=2, sticky=W)
for child in mf.winfo_children():
child.grid_configure(padx=5, pady=5)
feet_entry.focus()
root.bind('<Return>', calculate)
# this is the key line
root.bind('red', callback_function)
root.mainloop()
Upvotes: 4
Reputation: 386342
What you want is certainly possible. The solution depends on what you really want.
Do you want to turn something red only if the user types "turn me red" precisely? Or, if the text is "turn me blue" and they change the word "blue" to "red", will that trigger the action?
If the former (must type exactly "turn me red") you can just bind to that exact sequence (eg: widget.bind("<t><u><r><n><space><m><e>....", doSomething)
). It becomes impossible to manage, however, if you also want "Turn ME Red" to do the very same thing.
If the latter (whenever you type anything it looks to see if "turn it red" surrounds the insertion point), it's a tiny bit more work. You can bind on <KeyRelease>
and then look at the characters prior to the insertion point for the magic phrase.
Bottom line is, you set up a binding either on something generic like <KeyRelease>
then make the decision in the callback, or set up a highly specific binding for an exact phrase.
Upvotes: 1