我试图弄清楚如何在对话框窗口中对bind命令进行单元测试。我尝试使用tkinter event_generate
进行此操作。它不像我期望的那样工作。对于此StackOverflow问题,我通过一次调用event_generate
设置了一些代码。有时这条线有效,有时就好像线条甚至不存在一样。
对话框__init__
方法中的绑定如下所示:
self.bind('<BackSpace>', #Print "BackSpace event generated."
lambda event: print(event.keysym, 'event generated.'))
对话框中的任何操作都将回调其终止方法(该对话框基于Frederik Lundh的示例对话框&#39;简介Tkinter&#39;。)
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
。在每种情况下&#34;终止被叫&#34;和&#34;生成BackSpace事件。&#34;显示。这证明对event_generate的调用设置正确。
parent = tk.Tk()
dialog = Dialog(parent)
dialog.wait_window()
如果相关,我应该提一下,我已将Lundh的self.wait_window
电话从他的对话框的__init__
方法转移给来电者。虽然这打破了对话框的整洁封装,但似乎有必要进行自动化的单元测试。否则,unittest将显示对话框并停止等待用户输入。我不喜欢这个解决方案,但我不知道任何替代方案。
我遇到的问题是,wait_window
替换为直接调用terminate
方法。这是我希望能够在单元测试中做的事情,即在不运行tkinter的mainloop或wait_window的情况下测试我的GUI代码。
parent = tk.Tk()
dialog = Dialog(parent)
dialog.terminate()
这只打印&#34;终止被叫&#34;并且不打印&#34;生成BackSpace事件。&#34;。对event_generate
的调用似乎没有效果。如果我在调试器中跟随调用,我可以看到正在使用正确的参数调用tkinter event_generate()
。 self = {Dialog} .99999999, sequence = {str}'<BackSpace>', kw = {dict}{}
鉴于TkCmd手册页中关于窗口焦点的警告,我已经验证了绑定的对话框在其__init__
方法中得到了重点。
Tkinter没有执行回调。为什么呢?
编辑:这个裸骨代码显示update
正常工作。但是,只有在主程序调用{{1}}之前在__init__
中调用它才有效。 (这个谜题已被提升为separate question)
event_generate
答案 0 :(得分:6)
event_generate
会立即处理所有事件回调。但是,如果在调用event_generate
之前未调用update,则该窗口将不可见,并且tkinter可能会忽略任何事件。您可以使用when
属性控制何时处理生成的事件。默认值为“now”,但另一个选择是“tail”,这意味着在处理完任何事件(如重绘)后将其附加到事件队列。
when
属性的完整文档位于event_generate
的tcl / tk手册页上:http://tcl.tk/man/tcl8.5/TkCmd/event.htm#M34
答案 1 :(得分:1)
@lemi57ssss 我知道这是一个老问题,但我只想强调 Bryan Oakley 提出的观点并更正您的最后一个代码以使其工作。他说你必须先更新,然后它才能响应生成的事件。因此,如果您切换 update()
和 event_generate()
的位置,您将获得“生成的 BackSpace 事件”。文本打印出来。
当您将 update()
放入 __init__()
时它起作用是因为相同的原因,即它在 event_generated()
之前首先被调用。< /p>
请参阅下面的修正代码:
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.update() # Update also works if you placed it here
app.event_generate('<BackSpace>')
答案 2 :(得分:0)
不知道这是否与您的问题有关,但是我通过首先致电widget.event_generate()
使widget.focus_set()
正常工作。