【问题标题】:How to set the text/value/content of an `Entry` widget using a button in tkinter如何使用 tkinter 中的按钮设置“Entry”小部件的文本/值/内容
【发布时间】:2013-04-28 17:47:12
【问题描述】:

我正在尝试使用 tkinter 模块的 GUI 中的按钮设置 Entry 小部件的文本。

这个 GUI 可以帮助我将数千个单词分为五类。每个类别都有一个按钮。我希望使用按钮可以显着加快我的速度,并且我想每次都仔细检查单词,否则我只会使用按钮并让 GUI 处理当前单词并带来下一个单词。

由于某种原因,命令按钮的行为不像我想要的那样。这是一个例子:

import tkinter as tk
from tkinter import ttk

win = tk.Tk()

v = tk.StringVar()
def setText(word):
    v.set(word)

a = ttk.Button(win, text="plant", command=setText("plant"))
a.pack()
b = ttk.Button(win, text="animal", command=setText("animal"))
b.pack()
c = ttk.Entry(win, textvariable=v)
c.pack()
win.mainloop()

到目前为止,当我能够编译时,点击什么也没做。

【问题讨论】:

    标签: python events tkinter tkinter-entry


    【解决方案1】:

    您可能想使用insert 方法。 You can find the documentation for the Tkinter Entry Widget here.

    此脚本将文本插入Entry。插入的文字可以在Button的command参数中改变。

    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()
    

    【讨论】:

    • 只是想对新人说,你可能有import tkinter as tk,所以,e.delete(0,END)的那一行变成了e.delete(0,tk.END)
    • @m3nda: 是的,即使在使用import tkinter as tk 时,在它后面加上from tkinter.constants import * 仍然很方便,以避免模块中的许多常量使用tk. 定义前缀——尽管您也可以只使用不需要导入任何内容的文字字符串。即e.delete(0,'end')e.delete(0,'END')
    【解决方案2】:

    如果您使用“文本变量”tk.StringVar(),您可以只使用set()

    无需使用Entry delete 和insert。此外,当条目被禁用或只读时,这些功能不起作用!但是,文本变量方法也可以在这些条件下工作。

    import Tkinter as tk
    
    ...
    
    entryText = tk.StringVar()
    entry = tk.Entry( master, textvariable=entryText )
    entryText.set( "Hello World" )
    

    【讨论】:

    • 但是如果我已经有一个Entry 对象,我如何获得它的StringVar 对象?
    • 我猜您不想将StringVar 保留在范围内?我可以看到...好吧,看看这个 SO 线程:stackoverflow.com/questions/3221908/… 这显示了如何通过几种方式获取 Tk Widget 的属性。我没有测试它,但你应该可以通过这种方式访问​​textvariable
    • BuvinJ:如果您必须首先调用 cget() 来获取与 Entry 小部件相关联的 StringVar,这有点违背了在这种情况下使用 IMO 的目的。此外,当您回复其他人的评论时,您应该将 @ + 他们的用户名放入其中(您没有为 @Madlozoz 做的)。无论如何,我认为这是一个很好的答案。
    【解决方案3】:

    你的问题是当你这样做时:

    a = Button(win, text="plant", command=setText("plant"))
    

    它会尝试评估为命令设置的内容。所以在实例化Button对象时,它实际上调用了setText("plant")。这是错误的,因为您还不想调用 setText 方法。然后它获取此调用的返回值(None),并将其设置为按钮的命令。这就是为什么单击按钮什么都不做的原因,因为没有为它设置命令。

    如果您按照 Milan Skála 的建议进行操作并改用 lambda 表达式,那么您的代码将有效(假设您修复了缩进和括号)。

    您可以设置command=lambda:setText("plant"),而不是实际调用函数的command=setText("plant"),它指定稍后调用该函数的内容。

    如果你不喜欢 lambda,另一种(稍微麻烦一点)的方法是定义一对函数来做你想做的事:

    def set_to_plant():
        set_text("plant")
    def set_to_animal():
        set_text("animal")
    

    然后您可以使用command=set_to_plantcommand=set_to_animal - 它们将评估为相应的函数,但绝对command=set_to_plant() 相同,command=set_to_plant() 当然评估为None再次。

    【讨论】:

      【解决方案4】:

      一种方法是继承一个新类EntryWithSet,并定义set 方法,该方法利用Entry 类对象的deleteinsert 方法:

      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)
        

        【讨论】:

        • 如果您想将图像的位置放入条目小部件中
        猜你喜欢
        • 1970-01-01
        • 2012-04-06
        • 2014-10-26
        • 1970-01-01
        • 2011-01-16
        • 1970-01-01
        • 2022-01-03
        • 1970-01-01
        相关资源
        最近更新 更多