【问题标题】:python tkinter append listpython tkinter 追加列表
【发布时间】:2023-03-09 08:59:02
【问题描述】:

我是一名有 2 个月经验的业余 Python 程序员。我正在尝试通过 tkinter 编写一个 GUI 待办事项列表。按钮的实际位置并不重要。之后我可以和他们一起玩。我需要一些帮助来将附加项目显示到列表中。在程序中,它会很好地更新数字,但不会打印到列表中。我在控制台上仔细检查了它,它说“tkinter.StringVar object at 0x102fa4048”但没有更新实际列表。我需要帮助的是如何更新标签列上的 Main_Q 列表?非常感谢一些指导和编码帮助。谢谢。

Main_Q =["read","clean dishes", "wash car"]


from tkinter import*
root=Tk(className="total tasks in the Q")


#formula

def update():
global Main_Q
a=len(Main_Q)
num.set(a)

def add2list():
Main_Q.append(name)
a=len(Main_Q)
num.set(a)
print (Main_Q)


#output

num=StringVar()
y=Label(root, textvariable=num).grid(row=0, column=1)

#input

name=StringVar()
b=Entry(root, textvariable=name).grid(row=7,column=0)


#buttons
z=Button(root, text="update", command=update).grid(row=7, column=2)
add2list=Button(root,text="add", command=add2list).grid(row=7,         
column=1)


r = 0
for c in Main_Q:
Label(text=c, relief=RIDGE,width=15).grid(row=r,column=0)
r = r + 1

root.mainloop()

【问题讨论】:

    标签: python list tkinter append


    【解决方案1】:

    您的问题是,每次您输入新的“任务”后,都不会调用构建标签的 for 循环。要轻松解决此问题,您可以将此循环移动到更新函数中。

    如果您想防止每次循环遍历小部件,您可以创建一个包含所有已创建小部件的新列表:

    createdWidgets = []
    widgetsQueue = []
    

    在您的更新函数中,您不必遍历widgetsQueue(例如widgetsQueue.pop()),创建小部件并将小部件附加到createdWidgetes 列表中。

    def update():
        global Main_Q
        r = 0
        for c in Main_Q:
            Label(text=c, relief=RIDGE,width=15).grid(row=r,column=0)
            r += 1 # shorthand for r = r + 1
    

    一些补充说明:

    1. 对于条目,将定义和放置分开更容易:

      b = Entry(root)
      b.grid(row=7,column=0)
      

      因为比 Entry() 返回它的实例,您可以使用它来获取文本:

      b.get()
      
    2. 如果你去购物,你会把所有东西都放在一个袋子里吗?

      from tkinter import *
      

      确实如此(在这种情况下 globals() 变量将是包)。如果您想了解更多关于 Importing Python Modules 的信息。为了防止这种情况并缩短要输入的字母数量:

      import tkinter as t # or tk 
      root = t.Tk()
      

    *但是可以肯定的是,如果你只是想要一个小程序也没关系。

    【讨论】:

    • 下午好 Sense4。感谢 cmets 和方向。我做了你让我做的事情,即将for循环放入“更新”按钮。它现在在 for 循环中更新,但它仍然不打印我输入的内容。例如,如果我输入“shower”,它正在打印“PY_VAR1”。并且在 IDLE 中它正在打印 "。再次感谢。在弄清楚这一点之后,我将开始学习如何使用“销毁”功能和返回按钮进行更新。我会“挣扎“那些我自己先看看我能不能弄清楚。:)
    • 嘿,你应该看看我的补充说明。我不知道它是否也可以使用 stringVar,但我总是使用我在那里提到的方法作为条目。祝你好运。
    【解决方案2】:

    设计:

    要解决您的问题,您需要设计这个简单的解决方案:

    1. 使用get() 方法检索Tkinter.Entry 小部件的文本。
    2. 使用append() 方法将您在1 中获得的文本添加到Main_Q
    3. 使用command 方法绑定单击Main_Q 和您的GUI 时更新的按钮。
    4. 创建一个新的 Tkinter.Label 小部件,将其文本设置为您在 1 中获得的值,并在 GUI 中增加其对应的行。

    我更喜欢将您的代码组织在一个包含构造函数的类中,在该构造函数中初始化 Main_Q,以便我们调用 initialize_user_interface() 来使用它的三个元素初始化 GUI:

        def __init__(self, parent):
                Tkinter.Frame.__init__(self, parent)
                self.parent = parent
                self.Main_Q = ["read", "clean dishes", "wash car"]
                self.r = 0 # position of the row of each label
                self.initialize_user_interface()
    

    initialize_user_interface() 方法正如其名。我们主要绑定函数update_gui(),它使用command = self.update_gui插入一个新标签,并将文本设置为用户在Tkinter.Entry小部件中键入的内容command = self.update_gui

    ef initialize_user_interface(self):
            self.parent.title("Update GUI")
            self.parent.grid_rowconfigure(0, weight = 1)
            self.parent.grid_columnconfigure(0, weight = 1)
    
            for e in self.Main_Q:
                Tkinter.Label(self.parent, anchor = Tkinter.W, text = e).grid(row = self.r, sticky = Tkinter.W)
                self.r+=1
            self.entry_text = Tkinter.Entry(self.parent)
            self.entry_text.grid(row = 0, column = 1)
            self.button_update = Tkinter.Button(self.parent, text = "Update", command = self.update_gui).grid(row = 1, column = 1, sticky = Tkinter.E)
    

    最后,没有什么比update_gui()函数更简单了:

    def update_gui(self):
            self.r+=1 # increment the row reserved to the new label
            self.Main_Q.append(self.entry_text.get())
            Tkinter.Label(self.parent, anchor = Tkinter.W, text = self.entry_text.get()).grid(row = self.r, sticky = Tkinter.W)
    

    对应用程序进行编程:

    这是完整的程序:

    '''
    Created on Mar 11, 2016
    
    @author: Bill BEGUERADJ
    '''
    import Tkinter
    
    
    class Begueradj(Tkinter.Frame):
        def __init__(self, parent):
            Tkinter.Frame.__init__(self, parent)
            self.parent = parent
            self.main_queue = ["read", "clean dishes", "wash car"]
            self.r = 0
            self.initialize_user_interface()
    
    
        def initialize_user_interface(self):
            self.parent.title("Update GUI")
            self.parent.grid_rowconfigure(0, weight = 1)
            self.parent.grid_columnconfigure(0, weight = 1)
    
            for e in self.main_queue:
                Tkinter.Label(self.parent, anchor = Tkinter.W, text = e).grid(row = self.r, sticky = Tkinter.W)
                self.r+=1
            self.entry_text = Tkinter.Entry(self.parent)
            self.entry_text.grid(row = 0, column = 1)
            self.button_update = Tkinter.Button(self.parent, text = "Update", command = self.update_gui).grid(row = 1, column = 1, sticky = Tkinter.E)
    
        def update_gui(self):
            self.r+=1
            self.main_queue.append(self.entry_text.get())
            Tkinter.Label(self.parent, anchor = Tkinter.W, text = self.entry_text.get()).grid(row = self.r, sticky = Tkinter.W)
    
    
    def main():
        root = Tkinter.Tk()
        b = Begueradj(root)
        root.mainloop()
    
    if __name__ == "__main__":
        main()
    

    演示:

    下面是运行程序的截图:

    注意:

    我使用 Python 2.7 编写了之前的程序,所以如果你想测试它,请将 Tkinter 更改为 tkinter。其他一切都保持不变。

    【讨论】:

    • 嗨,比尔,非常感谢您的帮助。我从来没想过要写成这样。我有点理解课程的概念,但不是 100% 清楚。这个例子很有帮助。我想为这个小练习添加更多功能以进一步学习。再次感谢,暂时。
    • 不客气。如果您对我的代码有什么不明白的地方,请随时问我。 @鱼塘
    • 嗨,Bill,您能向我解释一下为什么有两个 init 语句吗?谢谢。我看到一些代码只有一个 init 语句,一些代码有 2 个。 class Begueradj(Tkinter.Frame): def __init__(self, parent): Tkinter.Frame.__init__(self, parent) self.parent = parent
    • 一个类不仅可以有一个或两个__init__(),还可以有更多,只要你想要/需要。这称为constructor。请花时间阅读并了解object oriented concepts。当你完成后,我会解释你剩下的问题。 @鱼塘
    • 比尔,我按照你的建议阅读了这篇文章。这就是我对 2 init 语句的理解。第一,你有一个根窗口,然后我们马上创建了一个框架类。第一个 init 语句是使类框架存在。第二个 init 语句是框架的实际实例。这是一个简单的,因为我可以理解它。我理解 OOP 的方式就像 3x5 卡片。有一张卡片的事实就像第一个 init 语句。当我们在第一张卡片上写一个名字或一个东西来创建我们想要的任何东西的第一个实例时,第二个语句就是第二个语句。 @BILL BEGUERADJ
    猜你喜欢
    • 2012-08-30
    • 1970-01-01
    • 2021-01-09
    • 2014-05-09
    • 2011-01-11
    • 1970-01-01
    • 2019-04-29
    • 2013-11-08
    相关资源
    最近更新 更多