Tkinter破坏顶层窗口也会破坏其他窗口

2024-09-27 23:20:44 发布

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

我在使用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类正是我所使用的,减去一些小的更改,因此它可以用于这个示例:


^{pr2}$

现在,如果您运行这个应用程序,请单击create并单击窗口的随机区域,然后尝试关闭一个。因为一个原因,每个窗口在试图摧毁一个窗口时都会关闭。我做了什么错事来制造这种行为?在


Tags: 示例bindcreatebuttonproperties逻辑windowcursor
1条回答
网友
1楼 · 发布于 2024-09-27 23:20:44

其他的窗户并没有被摧毁,它们只是被主窗口隐藏起来。如果创建一些弹出窗口,关闭其中一个,然后移动主窗口,就可以看到它们。在

要解决这个问题,请将主窗口降低到所有其他窗口的下方。更改的区域用#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()

相关问题 更多 >

    热门问题