gpt4 book ai didi

python - Tkinter 的 event_generate 命令被忽略

转载 作者:太空狗 更新时间:2023-10-29 21:46:13 32 4
gpt4 key购买 nike

我正在尝试弄清楚如何在对话框窗口中对绑定(bind)命令进行单元测试。我正在尝试使用 tkinter 的 event_generate .它没有按我预期的方式工作。对于这个 StackOverflow 问题,我设置了一些代码,只需一次调用 event_generate .有时这条线有效,有时好像这条线根本不存在。

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

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

对话框中的任何操作都会回调到它的终止方法(该对话框基于 Frederik Lundh 在“An Introduction to 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 .在每种情况下,“终止调用”和“生成退格键事件”。被显示。这证明对 event_generate 的调用设置正确。

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

如果相关,我应该提及我已将 Lundh 的电话转到 self.wait_window来自他的对话 __init__方法给调用者。虽然这打破了他的对话的整洁封装,但它似乎是自动化单元测试所必需的。否则单元测试将显示对话框并停止等待用户输入。我不喜欢这个解决方案,但我不知道有任何替代方案。

我遇到的问题是 wait_window替换为直接调用 terminate方法。这是我希望在单元测试中能够做的事情,即在不运行 tkinter 的 mainloop 或 wait_window 的情况下测试我的 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 手册页中有关窗口焦点的警告,我已经验证了带有绑定(bind)的对话框在其 __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

六年过去

2021 年 4 月 12 日。参见马克罗斯曼的 excellent web site详细解释为什么使用 update这是个坏主意。

更好的程序设计完全避免了这个六年前的问题所带来的问题,其中 tkinter 小部件对象从不子类化。相反,它们应该通过组合来创建,这样它们就可以很容易地进行猴子修补。 (此建议与 Frederik Lundh 在“Tkinter 简介”中的示例对话框中显示的模式相反。)对于单元测试设计,不仅不需要通过tkinter启动Tk/Tcl,而且也是不明智的。

最佳答案

event_generate 默认情况下会立即处理所有事件回调。但是,如果您在调用 event_generate 之前不调用更新,则窗口将不可见,tkinter 可能会忽略任何事件。您可以使用 when 属性控制何时处理生成的事件。默认值为“now”,但另一个选择是“tail”,这意味着在处理完任何事件(例如重绘)后将其附加到事件队列。

关于 when 属性的完整文档在 event_generate 的 tcl/tk 手册页上:http://tcl.tk/man/tcl8.5/TkCmd/event.htm#M34

关于python - Tkinter 的 event_generate 命令被忽略,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27581864/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com