python - Tkinter 销毁顶层窗口也会销毁其他窗口

标签 python python-2.7 tkinter

我在 Toplevel 窗口中遇到了这种非常奇怪的行为,我有一些这样的逻辑:

Did user click 'properties button?'
    yes? bind <ButtonPress-1> to window that will call properties(mouselocation)

properties(mouselocation):
    find location of cursor
    create property window at cursor

我遇到的问题是,不知何故,当我创建多个窗口并尝试关闭一个窗口时,它们全部都会关闭。我已经成功创建了一个突出显示我的问题的最小示例,PropertiesDialog 类正是我正在使用的类,减去了一些小更改,因此它可以用于此示例:

<小时/>
from Tkinter import *

class PropertyDialog(Toplevel):
    def __init__(self, root, string):
        Toplevel.__init__(self)
        self.wm_overrideredirect(1)
        self.\
             geometry('+%d+%d' %
                      (root.winfo_pointerx(),
                       root.winfo_pointery()))
        try:
            self.tk.call('::Tk::unsupported::MacWindowStyle',
                                         'style', self._w,
                                         'help', 'noActivates')
        except TclError:
            pass
        window_frame = Frame(self)
        window_frame.pack(side=TOP, fill=BOTH, expand=True)
        exit_frame = Frame(window_frame, background='#ffffe0')
        exit_frame.pack(side=TOP, fill=X, expand=True)
        button = Button(exit_frame, text='x', width=3, command=self.free,
               background='#ffffe0', highlightthickness=0, relief=FLAT)
        button.pack(side=RIGHT)
        text_frame = Frame(window_frame)
        text_frame.pack(side=TOP, fill=BOTH, expand=True)
        label = Label(text_frame, text=string, justify=LEFT,
                      background='#ffffe0',
                      font=('tahoma', '8', 'normal'))
        label.pack(ipadx=1)

    def free(self):
        self.destroy()

def bind():
    """
    toggle property window creation mode
    """
    root.bind('<ButtonPress-1>', create)


def create(event):
    """
    Create actual window upon mouse click
    """
    t = PropertyDialog(root, 'help me')
    return

root = Tk()
root.geometry('%dx%d' % (300,400))

Button(root, text='create', command=bind).pack()

root.mainloop()

现在,如果您运行此应用程序,请单击创建并单击窗口的随机区域,然后尝试关闭一个。出于一个原因,当试图只摧毁一扇 window 时,每一扇 window 都会关闭。我做错了什么造成这种行为?

最佳答案

其他窗口并没有被破坏,它们只是被主窗口隐藏了。如果您创建一些弹出窗口,关闭其中一个,然后移动主窗口,您就可以看到它们。

要解决此问题,请将主窗口降低到所有其他窗口下方。更改的区域用 #CHANGED# 标记:

from Tkinter import *

class PropertyDialog(Toplevel):
    def __init__(self, root, string):
        Toplevel.__init__(self)
        self.wm_overrideredirect(1)
        self.root = root #CHANGED# save a reference to the root
        self.\
             geometry('+%d+%d' %
                      (root.winfo_pointerx(),
                       root.winfo_pointery()))
        try:
            self.tk.call('::Tk::unsupported::MacWindowStyle',
                                         'style', self._w,
                                         'help', 'noActivates')
        except TclError:
            pass
        window_frame = Frame(self)
        window_frame.pack(side=TOP, fill=BOTH, expand=True)
        exit_frame = Frame(window_frame, background='#ffffe0')
        exit_frame.pack(side=TOP, fill=X, expand=True)
        button = Button(exit_frame, text='x', width=3, command=self.free,
               background='#ffffe0', highlightthickness=0, relief=FLAT)
        button.pack(side=RIGHT)
        text_frame = Frame(window_frame)
        text_frame.pack(side=TOP, fill=BOTH, expand=True)
        label = Label(text_frame, text=string, justify=LEFT,
                      background='#ffffe0',
                      font=('tahoma', '8', 'normal'))
        label.pack(ipadx=1)

    def free(self): #CHANGED# this method significantly
        self.destroy() # first we destroy this one
        for val,widget in enumerate(dialogs): # go through the dialogs list
            if widget is self: # when we find this widget
                dialogs.pop(val) # pop it out
                break # and stop searching
        if dialogs: # if there are any dialogs left:
            for widget in dialogs: # go through each widget
                widget.lift(aboveThis=self.root) # and lift it above the root

def bind():
    """
    toggle property window creation mode
    """
    root.bind('<ButtonPress-1>', create)


def create(event): #CHANGED# this to store the widget in a list
    """
    Create actual window upon mouse click
    """
    dialogs.append(PropertyDialog(root, 'help me'))

root = Tk()
dialogs = [] #CHANGED# to initialize a list
root.geometry('%dx%d' % (300,400))

Button(root, text='create', command=bind).pack()

root.mainloop()

关于python - Tkinter 销毁顶层窗口也会销毁其他窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31909580/

相关文章:

python - 如何隐藏默认标签 Django 模型表单?

python - 如何将此 DataFrame 转换为按索引值平均得分的 DataFrame?

python - Django Form Clean 方法测试错误

python - 子进程在后台运行时 GUI 上的 Tk 进度条?

python - 如何获得条目小部件来保存我输入的内容? Python Tkinter

Python 滚动文本模块

python - 一次导入 CSV 文件目录,每个文件只保留最旧的记录

python-2.7 - 将本地 IPython 笔记本连接到气隙集群上的 Spark

python - 在 BeautifulSoup 标签上使用正则表达式

python - Odoo/ python : modules dependencies gone wrong?