特金特挂在快速重复的对话

2024-09-22 16:25:45 发布

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

问题

当我通过按住Return键反复打开一个对话框时,程序 最终挂起并打开对话框。没有什么是可点击的,也没有键盘 快捷方式有效。如果我通过单击“离开”来取消对窗口的对焦,则单击“返回到” 它,挂断了。你知道吗

当我通过按住Shift Return键反复打开CustomDialog时,程序不会挂起。你知道吗

问题

  • 为什么Dialog类有时会使程序在快速重复打开时挂起?你知道吗
  • 为什么从CustomDialog继承并且只覆盖一行的Dialog类没有遇到这个问题?你知道吗

观察结果

  • 挂起并不总是发生。当 我同时运行cpu密集型命令,例如cat /dev/urandom。你知道吗
  • 单击“打开对话框”按钮(而不是按回车键)不会 似乎导致程序挂起。这可能是因为老鼠不能 以绑定的返回键可以调用的速度单击按钮 MainWindow.open_dialog()。你知道吗

示例代码

下面的代码创建了一个带有两个按钮的Tk窗口:

  • “打开对话框”打开tkinter.simpledialog.Dialog的实例。你知道吗
  • “打开自定义对话框”打开CustomDialog的实例,该实例继承 从tkinter.simpledialog.Dialog,但注释出一行(line 215)ok()方法中。你知道吗
  • 返回键绑定到“打开对话框”按钮。你知道吗
  • Shift+Return绑定到“打开自定义对话框”按钮。你知道吗
  • 设置:
    • 使用python3.5.2运行下面的代码。你知道吗
    • 按住返回键。你知道吗

你知道吗hangingdialog.py文件

import tkinter
from tkinter import ttk
from tkinter.simpledialog import Dialog


class MainWindow:

    def __init__(self):
        self.root = tkinter.Tk()

        self.btn_dialog = ttk.Button(
            self.root,
            text="Open Dialog",
            command=self.open_dialog,
        )

        self.btn_custom_dialog = ttk.Button(
            self.root,
            text="Open Custom Dialog",
            command=self.open_custom_dialog,
        )

        self.btn_dialog.pack()
        self.btn_custom_dialog.pack()

        self.root.bind('<Return>', self.open_dialog)
        self.root.bind('<Shift-Return>', self.open_custom_dialog)

        self.root.mainloop()

    def open_dialog(self, event=None):
        u = Dialog(self.root, 'Dialog')
        print('Dialog Opened.')

    def open_custom_dialog(self, event=None):
        u = CustomDialog(self.root, 'Custom Dialog')
        print('Custom Dialog Opened.')


class CustomDialog(Dialog):
    """This class is identical to is identical to
    tkinter.simpledialog.Dialog, but with
    'self.withdraw()' commented out in the self.ok()
    method.
    """

    def __init__(self, parent, title=None):
        tkinter.simpledialog.Dialog.__init__(self, parent, title)

    def ok(self, event=None):
        """This method is identical to
        tkinter.simpledialog.Dialog.ok(),
        but with 'self.withdraw()' commented out.
        """
        if not self.validate():
            self.initial_focus.focus_set() # put focus back
            return

        # Using self.withdraw() here causes the
        # ui to freeze until the window loses and regains
        # focus.
        #self.withdraw()
        self.update_idletasks()

        try:
            self.apply()
        finally:
            self.cancel()


if __name__ == '__main__':
    MainWindow()

Tags: self程序returntkinterdefcustomokroot