Python 3 Tkinter - 尝试通过一个按钮阻止多个窗口打开
Posted
技术标签:
【中文标题】Python 3 Tkinter - 尝试通过一个按钮阻止多个窗口打开【英文标题】:Python 3 Tkinter - Trying to stop multiple windows from opening with one button 【发布时间】:2018-10-24 02:48:56 【问题描述】:我有一个按钮可以在我的代码上打开一个新窗口,我一直在尝试让该按钮打开一个名为“newest_release_window”的新窗口,并考虑到两件事:
如果“newest_release_window”没有打开,打开窗口。 如果“newest_release_window”已打开,请将焦点设置在所述窗口上,但不要打开新窗口。不幸的是,它变得太复杂了,我一生都无法弄清楚如何去做。问题是我无法让代码检测“newest_release_window”是否打开,并据此更改变量。
welcome_window = Tk()
welcome_window.title("Games R Us")
welcome_window.geometry("360x350")
welcome_window.configure(bg = "gold")
currentDisplay = 10
newest_release_windowtracker = 0
gui_font_5 = ("Helvetica", 5, "bold")
gui_font_10 = ("Helvetica", 10, "bold")
gui_font_15 = ("Helvetica", 15, "bold")
gui_font_20 = ("Helvetica", 20, "bold")
space_between = (5)
button_variable = IntVar()
def newwindow_newest_release():
global newest_release_windowtracker
newest_release_window = Tk()
newest_release_window.title("Games R Us")
newest_release_window.geometry("360x350")
newest_release_window.configure(bg = "greenyellow")
currentDisplay = 10
display = Label(newest_release_window, text="Humm, see a new window !",
bg ="limegreen")
display.pack()
newest_release_window.withdraw()
if newest_release_windowtracker == 0:
newest_release_window.deiconify()
newest_release_windowtracker = 1
elif newest_release_windowtracker == 1:
newest_release_window.focus_set()
elif newest_release_window.winfo_exists == 0:
newest_release_window = Tk()
ww_newest_release = Button(welcome_window,
text = "Newest Release", bg = "goldenrod", font = "Helvetica 10",
width = 12, command = newwindow_newest_release)
注意:这不是完整的代码,我只是抓住了最重要的部分来说明问题可能是什么。
【问题讨论】:
我没有仔细检查你的代码,但我看到你在newwindow_newest_release
中有newest_release_window = Tk()
。该调用不仅创建了根窗口,还创建了执行所有 Tkinter 操作的 Tcl 解释器,而您真的不想要其中的一个。
而不是使用Tk()
使新窗口使用Toplevel()
。 Tk()
只能在 tkinter 中使用一次。 Toplevel()
是创建根窗口后创建新窗口的正确方法。
【参考方案1】:
我这样做的方法是使用一个变量来存储 Toplevel 实例。我先将该变量初始化为 None,所以我只能设置一次(通过测试变量是否为 None)
当 Toplevel 被销毁(通过绑定WM_DELETE_WINDOW
协议)时,该变量被重置回 None。
我还注意到,在您的代码中,您正在实例化一个新的 Tk()
对象。 Tk()
对象应该只被实例化一次,并且是你程序的根。要打开新窗口,您应该使用 Toplevel
对象。
现在举个例子:
import tkinter as tk
class OptionsWindow(tk.Frame):
def __init__(self, master=None, **kwargs):
super().__init__(master, **kwargs)
pass
class MainWindow(tk.Frame):
def __init__(self, master=None, **kwargs):
super().__init__(master, **kwargs)
self.options_toplevel = None
tk.Button(self, text='open toplevel', command=self._open_toplevel).pack()
def _open_toplevel(self, *args):
if self.options_toplevel is None:
self.options_toplevel = tk.Toplevel(self.master)
self.options_toplevel.protocol('WM_DELETE_WINDOW', self.on_tl_close)
gui = OptionsWindow(self.options_toplevel, width=300, height=300)
gui.pack()
def on_tl_close(self, *args):
self.options_toplevel.destroy()
self.options_toplevel = None
root = tk.Tk()
gui = MainWindow(root)
gui.pack()
root.mainloop()
【讨论】:
【参考方案2】:您可以设置一个布尔值来定义窗口是否打开,如果打开,则在tkinter.Tk
或tkinter.Toplevel
的实例上调用lift()
方法。
检查窗口是否存在:
如果newest_release
窗口上方有一个root 类,您可以检查hasattr(base_class, 'newest_release')
。如果没有,那么您可以像 global newest_release
这样将窗口设置为全局变量,以便您可以在函数外部访问它。然后你可以创建这样的代码:
if 'newest_release' in globals():
newest_release.lift()
或
if hasattr(base_class, 'newest_release'):
newest_release.lift()
【讨论】:
以上是关于Python 3 Tkinter - 尝试通过一个按钮阻止多个窗口打开的主要内容,如果未能解决你的问题,请参考以下文章
创建新建时关闭现有的顶层。 Tkinter Python 3
在 Python 3 中重命名了哪些 tkinter 模块?
为啥通过 Homebrew 安装的 Python 不包括 Tkinter