【问题标题】:Tkinter - setting string variables and getting entry values when loopingTkinter - 在循环时设置字符串变量并获取条目值
【发布时间】:2012-12-21 16:21:59
【问题描述】:

我的目标是能够将字符串变量传递给两个不同的条目以进行用户验证并返回用户修改的值。如果代码执行一次,则代码可以正常工作;但是,当循环时,它仅在循环的第一次迭代期间正确执行。在随后的迭代中,条目的字符串变量为空白。

我已经尝试过update_idletasks() 和时间睡眠,但没有运气。我在 Windows XP 上运行 Python 2.4。

# -*- coding: cp1252 -*-
import Tkinter

def retrieve_text():
    app_win.quit()

for item in range(3):

    numero_dossier = item+1
    version_dossier = item+2

    app_win = Tkinter.Tk()

    l = Tkinter.Label(app_win, text="Veuillez valider les informations suivantes et les corriger au besoin :")
    l.grid(row=0, column=0, columnspan=2)
    l.pack()

    v1 = Tkinter.StringVar()
    v1.set(numero_dossier)
    l1 = Tkinter.Label(app_win, text="Numéro de dossier:", anchor='w', justify='left')
    e1 = Tkinter.Entry(app_win, textvariable=v1)

    l1.pack()
    e1.pack()

    v2 = Tkinter.StringVar()
    v2.set(version_dossier)
    l2 = Tkinter.Label(app_win, text="Version du dossier:", anchor='w', justify='left')
    e2 = Tkinter.Entry(app_win, textvariable=v2)

    l2.pack()
    e2.pack()

    app_button = Tkinter.Button(app_win,text="OK",command=retrieve_text)
    app_button.pack()

    app_win.mainloop()

    app_win.withdraw()

    numero_dossier = e1.get().strip()
    version_dossier = e2.get().strip()

    print numero_dossier, version_dossier

【问题讨论】:

    标签: python loops tkinter tkinter-entry


    【解决方案1】:

    这从根本上被打破了:

    for item in range(3):
        ...
        app_win = Tkinter.Tk()
    

    Tkinter 根本不是为这种方式工作而设计的。您的程序应该只创建一个类Tk 的实例,并且您应该只调用一次mainloop

    【讨论】:

    • 为帮助干杯!我将 Tk 对象移出循环,因此它只被调用一次。我怎样才能实现我在帖子开头所述的目标?似乎应该有可能采用不同的逻辑方法?
    【解决方案2】:

    关于为什么要多次构建小部件的问题没有任何理由,所以我认为这是一个错误。此外,Tkinter.Tk 实例的名称 app_win 可能会欺骗您。实例化Tkinter.Tk 会启动一个 tcl 解释器,然后加载 tk 作为“奖励”给你一个窗口。

    更明智的方法是只创建一次小部件,然后进行多次验证。这是为此调整的代码:

    import Tkinter
    
    NUM_D = range(3)
    VER_D = range(3)
    CURR_D = 0
    
    def retrieve_and_update_text():
        global CURR_D
        num_d = e1.get().strip()
        ver_d = e2.get().strip()
        print num_d, ver_d
    
        CURR_D = (CURR_D + 1) % 3
        v1.set(NUM_D[CURR_D] + 1)
        v2.set(VER_D[CURR_D] + 2)
    
    
    root = Tkinter.Tk()
    
    l = Tkinter.Label(root, text=u"Label")
    l.grid(row=0, column=0, columnspan=2)
    
    v1 = Tkinter.StringVar()
    
    l1 = Tkinter.Label(root, text=u"Num", anchor='w', justify='left')
    e1 = Tkinter.Entry(root, textvariable=v1)
    l1.grid(row=1)
    e1.grid(row=1, column=1)
    
    v2 = Tkinter.StringVar()
    l2 = Tkinter.Label(root, text=u"Ver", anchor='w', justify='left')
    e2 = Tkinter.Entry(root, textvariable=v2)
    l2.grid(row=2)
    e2.grid(row=2, column=1)
    
    app_button = Tkinter.Button(root, text=u"OK", command=retrieve_and_update_text)
    app_button.grid(row=3)
    
    v1.set(NUM_D[CURR_D] + 1)
    v2.set(VER_D[CURR_D] + 2)
    
    root.mainloop()
    

    【讨论】:

    • 这正是我所需要的,只是“确定”按钮不会刷新 GUI。相反,关闭程序的“x”按钮似乎可以做到这一点。
    • 您想以哪种方式刷新 GUI?通过删除条目中的值?
    • 按“确定”按钮,StringVar 和条目值应刷新为新的 num_d、ver_d 变量。干杯!
    • 啊,对。这已经发生在这里,您很可能需要确保显示更新。在这种情况下,请在函数 retrieve_and_update_text 的末尾添加行 root.update_idletasks()
    【解决方案3】:

    感谢 Bryan Oakley 和 mmgp,我能够提出以下代码来满足我的需要,即使我在循环的每次迭代期间都调用了 mainloop 规则。欢迎所有的cmets。再次感谢!

    # -*- coding: cp1252 -*-
    import Tkinter
    root = Tkinter.Tk()
    
    def retrieve_and_update_text():
        #global CURR_D
        dossier = e1.get().strip()
        version = e2.get().strip().upper()
        print dossier, version
    
        root.quit()
    
    for item in range(3):
    
        dossier = item+1
        version = item+2
    
        l = Tkinter.Label(root, text=u"Veuillez valider les informations suivantes et les corriger au besoin :")
        l.grid(row=0, column=0, columnspan=2)
    
        v1 = Tkinter.StringVar()
    
        l1 = Tkinter.Label(root, text=u"Dossier :", anchor='w', justify='left')
        e1 = Tkinter.Entry(root, textvariable=v1)
        l1.grid(row=1)
        e1.grid(row=1, column=1)
    
        v2 = Tkinter.StringVar()
        l2 = Tkinter.Label(root, text=u"Version :", anchor='w', justify='left')
        e2 = Tkinter.Entry(root, textvariable=v2)
        l2.grid(row=2)
        e2.grid(row=2, column=1)
    
        app_button = Tkinter.Button(root, text=u"OK", command=retrieve_and_update_text)
        app_button.grid(row=3)
    
        v1.set(dossier)
        v2.set(version)
    
        root.mainloop()
    
        if item == range(3)[-1]: # if last item
            root.withdraw()
    

    【讨论】:

    • 对于任何访问此站点以了解 Tkinter 的人来说,此代码是一个非常糟糕的示例。真的,我不明白你为什么坚持要重做几乎所有错误的事情。如果您想使用它,请参阅pastebin.com/hB5vjqbL 以获取使用withdraw 的略有不同的retrieve_and_update_text
    • 感谢您的评论。我会说我一点也不坚持做错事。代码简单易读,最重要的是,它适用于我的用例。如果有更好的做事方式,我很乐意了解它们。
    • 我尝试指出一种更好的方法,但显然我失败了。抱歉粗鲁,请享受代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 2021-06-29
    • 2015-04-20
    • 1970-01-01
    • 2019-07-28
    相关资源
    最近更新 更多