我对Tk相对缺乏经验,但之前我做过一些简单的项目,这让我很难过:
我有一个表示时间滑块的比例小部件。一个threading.Timer每隔一段时间就会移动缩放小部件。按下按钮,线程被禁用;在按钮上,线程重新启用。因此,用户可以单击并拖动时间滑块以重新定位应用程序的“时间”。在UI操作期间禁用线程到目前为止防止了我遇到的崩溃我认为与线程安全有关(看似非确定性崩溃,发生在线程尝试更新滑块的时间)。
唯一的其他“活动”UI元素是一系列按钮,使用command = fnc参数进行配置。比例是我使用bind()的唯一地方。该应用程序是一个全屏应用程序,因此我在根级别使用self.root.overridedirect(1)和geometry()来删除菜单和边框,并使其全屏显示。
我已经更改了代码,因此缩放窗口小部件现在位于Frame内而不是绝对根级别:
self.scale_timescrub = tkinter.Scale(self.root.master, from_=0, to=60, width=height_one, orient=tkinter.HORIZONTAL, showvalue=0)
self.scale_timescrub.grid(row=2,column=0,sticky=tkinter.N+tkinter.S+tkinter.E+tkinter.W)
self.scale_timescrub.bind('<Button-1>', self.press_scrub)
self.scale_timescrub.bind('<ButtonRelease-1>', self.release_scrub)
现在,只要我使用scale小部件尝试任何UI操作,应用程序就会挂起。按下滑块上的任意位置固定CPU,应用程序永远不会回来。我知道它与育儿有关,因为当我破解应用程序将规模放回根级别时,它再次起作用。小部件似乎永远不会输入它的绑定函数,比如press_scrub,当它是框架的父级时。
有谁能告诉我这里我做错了什么?
在Windows 7上运行python 3.2.3 64b。
答案 0 :(得分:0)
你写道:“一个threading.Timer每隔一段时间就会移动缩放小部件”。在处理此计时器事件时,您是否从另一个线程调用窗口小部件方法?如果是这样,那肯定是问题所在。您根本无法从另一个线程更改UI。
您不应该需要Timer对象 - 您是否知道可以使用after
计划定期运行某些内容?
要考虑的另一件事,但无法通过查看您的代码片段来确定,是您是否在同一个容器小部件中使用pack
。在同一主数据中合并pack
和grid
将导致您看到的行为。通常你会在这种情况下看到启动时的行为,但并非总是如此。
答案 1 :(得分:0)
问题似乎在于我使用&#34; master&#34; keyword是我的全窗口Frame对象的名称。当我将self.root.master批量重命名为self.root.full_frame时,一切都按预期工作。感谢Bryan指出线程危险,我将用它来重新评估我的应用程序的其他方面。感谢mgilson表示对可重复的兴趣。在发布之前我没有配对可复制的因为我认为我设置了很多奇怪的配置,其中任何一个都可能参与其中。无论如何,感谢所有人。自我注意:不要打电话给任何人#34;掌握。&#34;