Python 3.4.3 tkinter - 程序在声明 IntVar 或任何其他 tkinter 数据类型时冻结 [英] Python 3.4.3 tkinter - Program freezes on declaration of IntVar or any other tkinter data type

查看:24
本文介绍了Python 3.4.3 tkinter - 程序在声明 IntVar 或任何其他 tkinter 数据类型时冻结的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

上一个线程:Python 3.4 tkinter checkbutton 变量处理不工作/响应

经过一个长线程,问题似乎与运行 root.mainloop() 之前的 IntVar 声明有关.显然,一旦进行了语法更改,上一个线程中的代码就可以与 Python 2.6.6 一起使用(感谢 PM 2Ring).您可以在上一个线程中查看完整代码.这是一个(大致)最小、完整且可验证的示例:

Following a long thread the problem appears to be related to the declaration of an IntVar before root.mainloop() is run. Apparently the code from the previous thread works with Python 2.6.6 (thanks to PM 2Ring) once syntactical changes are made. You can see the full code on the previous thread. Here is a (roughly) Minimal, Complete, and Verifiable example:

import tkinter as tk

class Thing(tk.Frame):

    def Switch(self):
        if self.anyVar.get():
            state = "disabled"
        else:
            state = "normal"
        print(state)

        self.entry.configure(state=state)

    def createWidgets(self):

        ### This is the problem.
        print("testbefore")
        self.anyVar = tk.IntVar()
        print("testafter")
        ### End of problem. testafter is never printed. BUT WHY?!?!

        tk.Label(self,text="Test",font=("Times New Roman",15)).grid(row=0,column=0,sticky="W",padx=5,pady=5)
        self.box = tk.Checkbutton(self,variable=self.anyVar,command=self.Switch)
        self.box.grid(row=1,column=1,sticky="W",padx=0,pady=5)
        self.entry = tk.Entry(self,width=2)
        self.entry.grid(row=2,column=1,sticky="W",padx=2,pady=5)

    def __init__(self, parent):

        tk.Frame.__init__(self, parent)
        self.pack()
        self.parent = parent
        self.createWidgets()

class Framework(tk.Frame):

    def __init__(self, parent):

        tk.Frame.__init__(self, parent)
        self.instances = []
        self.parent = parent
        thing = Thing(self)
        self.instances.append(thing)

    def Activity(self):

        self.Clear()
        self.instances[0].pack()


def Initialise(window):
    window.master = tk.Frame(window)
    window.master.grid()
    window.instances = Framework(window.master)
    window.instances.grid()

root = tk.Tk()
Initialise(root)
root.mainloop()
root.destroy()

代码将一直执行,直到达到 self.anyVar = tk.IntVar(),此时程序会冻结,但不会给出错误消息.testafter"从不打印.知道这是为什么吗?谢谢.

The code will execute until self.anyVar = tk.IntVar() is reached, at which point the program freezes but no error message is given. "testafter" is never printed. Any idea why this is? Thanks.

推荐答案

(注意:我最初的回答与gridpack 的使用有关.那个答案不正确.这是正确答案)

(note: my original answer was related to the use of grid and pack. That answer was incorrect. This is the correct answer)

您偶然发现了一个非常模糊的边缘情况,它在 python 2.6 中不存在,但在至少某些版本的 python 3 中确实存在.

You have stumbled on a very obscure edge case that doesn't exist in python 2.6, but does exist in at least some versions of python 3.

我正在 3.4 上测试它.在那个版本中,变量处理代码中引入了一些新代码.您的代码导致此新代码进入无限循环.问题围绕您选择使用 master 作为小部件属性的名称.这是您要覆盖的内置属性,导致代码进入无限循环.

I'm testing it on 3.4. In that version there's been some new code introduced in the variable handling code. Your code causes this new code to go into an infinite loop. The problem revolves around your choice to use master as the name of a widget attribute. This is a built-in attribute that you are overwriting, causing the code to go into an infinite loop.

解决方法很简单:将 window.master 重命名为 master 以外的任何名称.例如:

The workaround is simple: rename window.master to be just about anything other than master. For example:

window._master = tk.Frame(window)

这篇关于Python 3.4.3 tkinter - 程序在声明 IntVar 或任何其他 tkinter 数据类型时冻结的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆