这是我的计划中非常重要的一部分,我需要尽快整理出来,所以任何事都会有很大的帮助。
我的程序包含三个相互导入的模块。一个模块由我使用tkinter的用户界面组成。用户在画布上输入数据,然后发送到第二个要处理的程序,然后发送到第三个模块,该模块包含我打算与用户一起执行的算法。
“第一”和“第三”模块可以相互交互,在解释算法的某些点上,我改变了画布的外观和界面上的一些文本。然后第三个模块应暂停(我目前正在使用基本的睡眠方法),并等待(理想情况下,它将等待用户按下用户界面上的“下一步”按钮)。在此步骤中,我的界面决定要冻结。
有什么办法可以阻止这个吗?
非常感谢提前。
编辑:我找到了解决此问题的方法。谢谢你的所有建议!
答案 0 :(得分:4)
调用time.sleep()
将阻止程序执行任何操作,直到完成睡眠。您需要Tkinter继续处理事件,直到它应该运行代码的下一部分。
为此,将代码的下一部分放在一个单独的函数中,让Tkinter在它准备就绪时调用它。通常,您希望在用户触发它时发生这种情况(例如,通过单击按钮),因此您需要将其绑定到事件(docs)。如果您确实希望在固定时间之后发生,则可以在任何tkinter小部件(docs)上使用.after()
方法。
GUI编程需要一些习惯。你不会把一系列事情一个接一个地编码,你编写单独的代码,这些代码由用户所做的事情触发。
术语说明:如果您的Python文件相互导入,则您有三个模块,但它仍然是一个程序。谈论“第一个程序”会让人感到困惑。
答案 1 :(得分:1)
H.E.P - 传统的方法确实涉及使用单独的线程并协调工作人员之间的工作。线程和GUI线程使用某种轮询或事件机制。
但是,正如托马斯·K所指出的那样,这可能变得非常复杂和棘手,特别是在Python使用全球解释器锁(GIL)等方面,并且还必须应对Tkinter的处理循环。(使用多线程GUI的唯一理由是,如果您绝对必须确保GUI在可能长时间运行的后台任务期间保持响应,在这种情况下我不相信这是问题。 )
我建议的是基于生成器的"协同例程"型架构。 正如在#34; Python(2.7)语言参考",第6.8节中所述,[" yield"在定义生成器函数时使用语句,并且仅在生成器函数的主体中使用。在函数定义中使用yield语句足以使该定义创建生成器函数而不是正常函数。]
(这有效地构成了共同例程架构的基础。(编辑))
[当调用生成器函数时,它返回一个称为生成器迭代器的迭代器,或者更常见的是生成器。生成器函数的主体通过重复调用生成器的next()方法来执行,直到它引发异常。
执行yield语句时,生成器的状态被冻结,expression_list的值返回给next()的调用者。 “冻结”是指保留所有本地状态,包括局部变量,指令指针和内部评估堆栈的当前绑定:保存足够的信息,以便下次调用next()时,函数可以完全像yield语句只是另一个外部调用一样继续。] (另请参阅" PEP 0342 - 通过增强型发生器的协同程序"有关其他背景和一般信息。)
这应该允许您的GUI根据需要调用算法规范生成器的下一部分,而不必在操作员按下" Next"之前将其置于睡眠状态。按钮。 你基本上只是创建一个特定于域的语言'(DSL),它只包含你演示这个特定算法的步骤列表,而生成器(迭代器)只会执行每个下一个调用时(按需)。
更简单,更容易维护。
答案 2 :(得分:0)
GUI程序始终等待某些操作发生。当确实发生了动作时,执行与该动作对应的事件代码。因此,无需致电sleep()
。您需要做的就是设置它,以便从相应的事件中执行第三个程序。