0

我对 Tk 相对缺乏经验,但我之前做过一些简单的项目,这让我很难过:

我有一个代表时间滑块的比例小部件。threading.Timer 每隔一段时间就会关闭以移动比例小部件。按下按钮时,线程被禁用;在按钮上,线程被重新启用。因此,用户可以单击并拖动时间滑块来重新定位应用程序的“时间”。到目前为止,在 UI 操作期间禁用线程已经防止了我认为与线程安全有关的崩溃(看似不确定的崩溃,发生在线程试图更新滑块的时间)。

唯一的其他“活动” UI 元素是一系列按钮,这些按钮使用 command=fnc 参数进行配置。规模是我使用绑定()的唯一地方。该应用程序是全屏应用程序,因此我在根级别使用 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)

现在,每当我尝试使用缩放小部件进行任何 UI 操作时,应用程序都会挂起。按下滑块上的任何位置都会锁定 CPU,并且应用程序永远不会返回。我知道这与育儿有关,因为当我破解应用程序以将规模放回根级别时,它又可以工作了。当它是框架的父级时,小部件似乎永远不会进入它的绑定函数,如 press_scrub。

谁能告诉我我在这里做错了什么?

在 Windows 7 上运行 python 3.2.3 64b。

4

2 回答 2

0

您写道:“一个 threading.Timer 每隔一段时间就会关闭以移动比例小部件”。在处理此计时器事件时,您是否从另一个线程调用小部件方法?如果是这样,那肯定是问题所在。您根本无法从另一个线程更改 UI。

你不应该需要一个 Timer 对象——你知道你可以安排一些东西定期运行after吗?

要考虑的另一件事,但不能通过查看您的代码片段来确定,是您是否pack在同一个容器小部件中使用。结合packgrid在同一个主人中会导致你看到的行为。通常,在这种情况下,您会在启动时看到这种行为,但并非总是如此。

于 2012-05-21T11:10:53.013 回答
0

问题似乎在于我使用“master”关键字作为全窗口 Frame 对象的名称。当我将 self.root.master 批量重命名为 self.root.full_frame 时,一切都按预期工作。感谢 Bryan 指出线程危险,我将用它来重新评估我的应用程序的其他方面。感谢 mgilson 对可重现性表现出兴趣。在发布之前,我没有配对可复制,因为我认为我设置了太多奇怪的配置,以至于其中任何一个都可能涉及。无论如何,谢谢大家。自我提醒:不要称任何东西为“大师”。

于 2012-05-21T19:55:18.427 回答