在tkinter中创建模态对话框

时间:2018-05-18 18:00:40

标签: python tkinter dialog modal-dialog python-2.x

这个问题不重复:见下文。

我想在tkinter中创建一个模态对话框。换句话说,一个对话框,当它处于活动状态时,会阻止用户与父窗口进行交互。 SO上有an existing question回答此问题,并且有一个full example说明了这个概念。

但是,在Windows 7或Ubuntu 16.04.4 LTS上,使对话框成为Toplevel并在其上调用grab_set()根本不起作用。用户仍然可以关闭,调整大小,并且通常与父窗口进行交互。

有没有办法在Tkinter中创建一个实际有效的模态对话框?

这是dialog.grab_set()的最小用法示例,无法阻止与父窗口的交互:

import os
try:
    import Tkinter as tkinter
except ImportError:
    import tkinter

class MyToplevel(tkinter.Toplevel, object):
    def __init__(self, parent):
        tkinter.Toplevel.__init__(self, parent)

        self.title("Main window")
        MyDialog(self)

        self.protocol("WM_DELETE_WINDOW", parent.destroy)

class MyDialog(tkinter.Toplevel, object):
    def __init__(self, parent):
        tkinter.Toplevel.__init__(self, parent)

        self.transient(parent)
        self.title("Dialog")
        self.grab_set()

        self.protocol("WM_DELETE_WINDOW", self.destroy)

if __name__ == "__main__":
    root = tkinter.Tk()
    root.withdraw()
    app = MyToplevel(root)
    app.mainloop()

我应该指出,使用grab_set_global()(如在this answer中)确实有效,但它不是一个可行的解决方案,因为它会阻止对整个系统的所有窗口的访问。

1 个答案:

答案 0 :(得分:0)

这是(至少在Windows上)特定于版本的问题。要使其适用于python2.7,只需在self.focus_force()之前添加self.grab_set()

def __init__(self, parent):
    tkinter.Toplevel.__init__(self, parent)

    self.transient(parent)
    self.title("Dialog")

    self.focus_force() # added
    self.grab_set()

    self.protocol("WM_DELETE_WINDOW", self.destroy)