忽略Tkinter的事件生成命令

2024-10-02 16:22:51 发布

您现在位置:Python中文网/ 问答频道 /正文

我正试图找出如何在对话框窗口中对bind命令进行unittest。我用tkinter的event_generate来尝试这个。它不像我期望的那样工作。对于这个StackOverflow问题,我设置了一些代码,只需调用event_generate。有时候这条线起作用了,有时候就好像这条线根本不存在似的。

对话框的__init__方法中的绑定如下所示:

        self.bind('<BackSpace>',  #Print "BackSpace event generated."
            lambda event: print(event.keysym, 'event generated.'))

对话框中的任何操作都将调用其terminate方法(该对话框基于Frederik Lundh在“Tkinter简介”中的示例对话框)

    def terminate(self, event=None):
        print('terminate called')  # Make sure we got here and the next line will be called
        self.event_generate('<BackSpace>')
        self.parent.focus_set()
        self.destroy()

当使用下面的代码调用对话框时,任何用户操作都将最终调用terminate。在每种情况下都会显示“terminate called”和“BackSpace event generated.”。这证明对event_generate的调用设置正确。

parent = tk.Tk()
dialog = Dialog(parent)
dialog.wait_window()

如果相关的话,我应该提到,我已经将Lundh对self.wait_window的调用从他的对话框的__init__方法移动到调用方。虽然这打破了他对话框的简洁封装,但它似乎是自动单元测试所必需的。否则unittest将显示对话框并停止等待用户输入。我不喜欢这个解决方案,但我不知道有什么选择。

我遇到的问题是当wait_window被替换为对terminate方法的直接调用时。这是我在unittesting中希望能够做的事情,unittesting是在不运行tkinter主循环或wait_窗口的情况下测试我的GUI代码。

parent = tk.Tk()
dialog = Dialog(parent)
dialog.terminate()

这只打印“terminate called”,而不打印“BackSpace event generated.”。对event_generate的调用似乎没有效果。如果我跟踪调试器中的调用,我可以看到tkinter的event_generate()正在使用正确的参数调用。self = {Dialog} .99999999, sequence = {str}'<BackSpace>', kw = {dict}{} 鉴于TkCmd手册页中关于窗口焦点的警告,我已经验证了在其__init__方法中为具有绑定的对话框指定了焦点。

Tkinter没有执行回调。为什么?

编辑:这段代码显示update正在工作。但是,它只有在主程序调用__init__之前在event_generate中调用时才起作用。(这个拼图是作为separate question提出的)

class UpdWin(tk.Tk):
    def __init__(self):
        super().__init__()
        self.bind('<BackSpace>',
                  lambda event: print(event.keysym, 'event generated.'))
        self.update()  # Update works if placed here


app = UpdWin()
app.event_generate('<BackSpace>')
# app.update() # Update doesn't work if placed here

Tags: 方法代码selfeventinitbindgenerategenerated