问题
I am trying to set the text of an Entry widget using a button in a GUI using the tkinter module.
This GUI is to help me classify thousands of words into five categories. Each of the categories has a button. I was hoping that using a button would significantly speed me up and I want to double check the words every time otherwise I would just use the button and have the GUI process the current word and bring the next word.
The command buttons for some reason are not behaving like I want them to. This is an example:
win = Tk()
v = StringVar()
def setText(word):
v.set(word)
a = Button(win, text=\"plant\", command=setText(\"plant\")
a.pack()
b = Button(win, text=\"animal\", command=setText(\"animal\"))
b.pack()
c = Entry(win, textvariable=v)
c.pack()
win.mainloop()
So far, when I am able to compile, the click does nothing.
回答1:
You might want to use insert method.
This script inserts a text into Entry. The inserted text can be changed in command parameter of the Button.
from tkinter import *
def set_text(text):
e.delete(0,END)
e.insert(0,text)
return
win = Tk()
e = Entry(win,width=10)
e.pack()
b1 = Button(win,text="animal",command=lambda:set_text("animal"))
b1.pack()
b2 = Button(win,text="plant",command=lambda:set_text("plant"))
b2.pack()
win.mainloop()
回答2:
If you use a "text variable" tk.StringVar(), you can just set() that.
No need to use the Entry delete and insert. Moreover, those functions don't work when the Entry is disabled or readonly! The text variable method, however, does work under those conditions as well.
import Tkinter as tk
...
entryText = tk.StringVar()
entry = tk.Entry( master, textvariable=entryText )
entryText.set( "Hello World" )
回答3:
You can choose between the following two methods to set the text of an Entry widget. For the examples, assume imported library import tkinter as tk and root window root = tk.Tk().
Method A: Use
deleteandinsertWidget
Entryprovides methodsdeleteandinsertwhich can be used to set its text to a new value. First, you'll have to remove any former, old text fromEntrywithdeletewhich needs the positions where to start and end the deletion. Since we want to remove the full old text, we start at0and end at wherever the end currently is. We can access that value viaEND. Afterwards theEntryis empty and we can insertnew_textat position0.entry = tk.Entry(root) new_text = "Example text" entry.delete(0, tk.END) entry.insert(0, new_text)
Method B: Use
StringVarYou have to create a new
StringVarobject calledentry_textin the example. Also, yourEntrywidget has to be created with keyword argumenttextvariable. Afterwards, every time you changeentry_textwithset, the text will automatically show up in theEntrywidget.entry_text = tk.StringVar() entry = tk.Entry(root, textvariable=entry_text) new_text = "Example text" entry_text.set(new_text)
Complete working example which contains both methods to set the text via
Button:This window
is generated by the following complete working example:
import tkinter as tk def button_1_click(): # define new text (you can modify this to your needs!) new_text = "Button 1 clicked!" # delete content from position 0 to end entry.delete(0, tk.END) # insert new_text at position 0 entry.insert(0, new_text) def button_2_click(): # define new text (you can modify this to your needs!) new_text = "Button 2 clicked!" # set connected text variable to new_text entry_text.set(new_text) root = tk.Tk() entry_text = tk.StringVar() entry = tk.Entry(root, textvariable=entry_text) button_1 = tk.Button(root, text="Button 1", command=button_1_click) button_2 = tk.Button(root, text="Button 2", command=button_2_click) entry.pack(side=tk.TOP) button_1.pack(side=tk.LEFT) button_2.pack(side=tk.LEFT) root.mainloop()
回答4:
One way would be to inherit a new class,EntryWithSet, and defining set method that makes use of delete and insert methods of the Entry class objects:
try: # In order to be able to import tkinter for
import tkinter as tk # either in python 2 or in python 3
except ImportError:
import Tkinter as tk
class EntryWithSet(tk.Entry):
"""
A subclass to Entry that has a set method for setting its text to
a given string, much like a Variable class.
"""
def __init__(self, master, *args, **kwargs):
tk.Entry.__init__(self, master, *args, **kwargs)
def set(self, text_string):
"""
Sets the object's text to text_string.
"""
self.delete('0', 'end')
self.insert('0', text_string)
def on_button_click():
import random, string
rand_str = ''.join(random.choice(string.ascii_letters) for _ in range(19))
entry.set(rand_str)
if __name__ == '__main__':
root = tk.Tk()
entry = EntryWithSet(root)
entry.pack()
tk.Button(root, text="Set", command=on_button_click).pack()
tk.mainloop()
回答5:
e= StringVar()
def fileDialog():
filename = filedialog.askopenfilename(initialdir = "/",title = "Select A
File",filetype = (("jpeg","*.jpg"),("png","*.png"),("All Files","*.*")))
e.set(filename)
la = Entry(self,textvariable = e,width = 30).place(x=230,y=330)
butt=Button(self,text="Browse",width=7,command=fileDialog).place(x=430,y=328)
回答6:
Your problem is that when you do this:
a = Button(win, text="plant", command=setText("plant"))
it tries to evaluate what to set for the command. So when instantiating the Button object, it actually calls setText("plant"). This is wrong, because you don't want to call the setText method yet. Then it takes the return value of this call (which is None), and sets that to the command of the button. That's why clicking the button does nothing, because there is no command set for it.
If you do as Milan Skála suggested and use a lambda expression instead, then your code will work (assuming you fix the indentation and the parentheses).
Instead of command=setText("plant"), which actually calls the function, you can set command=lambda:setText("plant") which specifies something which will call the function later, when you want to call it.
If you don't like lambdas, another (slightly more cumbersome) way would be to define a pair of functions to do what you want:
def set_to_plant():
set_text("plant")
def set_to_animal():
set_text("animal")
and then you can use command=set_to_plant and command=set_to_animal - these will evaluate to the corresponding functions, but are definitely not the same as command=set_to_plant() which would of course evaluate to None again.
来源:https://stackoverflow.com/questions/16373887/how-to-set-the-text-value-content-of-an-entry-widget-using-a-button-in-tkinter