Python Tkinter面向对象编程:解决顶级窗口绑定按钮最小化(iconify)功能的实现问题
解决面向对象Tkinter中顶级窗口按钮最小化的问题
让我们一步步拆解你遇到的问题,以及如何正确实现需求:
第一个错误代码的问题分析
你最初的面向对象代码里,子窗口按钮的command参数写法存在两处关键错误:
self.btn = tk.Button(window, text="click", command=lambda window: self.test(*window)).pack()
- 你给lambda定义了
window参数,但按钮点击时Tkinter不会给回调函数传参,因此会触发"missing 1 required positional argument"的报错; *window是完全多余的解包操作,你只需要把当前创建的window对象直接传给test方法即可;- 额外提一句:重复用
self.btn存储子窗口按钮没必要(还会覆盖主窗口按钮的引用),这个按钮不需要在其他方法中访问,用局部变量或者直接创建就行。
绑定事件方式的问题分析
你尝试用bind("<Button-1>", self.test(window=window))时,犯了Tkinter绑定的常见错误:
bind方法需要接收函数对象作为回调,但self.test(window=window)是直接调用了test方法,返回值是None,相当于你绑定了None作为回调,所以点击按钮不会有任何反应;- 如果想用绑定事件的方式实现,需要用lambda接收Tkinter自动传递的
event参数,同时把window传进去,正确写法是:self.btn.bind("<Button-1>", lambda event, win=window: self.test(win))
正确的实现方式
你最后写出的代码是完全正确的,核心就是用lambda: self.test(window)把当前的顶级窗口对象传递给test方法,同时避免了不必要的self变量引用:
import tkinter as tk from tkinter import ttk class GUI: def __init__(self): self.root = tk.Tk() self.root.title('title') self.root.geometry("300x200+500+250") self.root.resizable(False, False) self.interface() self.root.iconbitmap("tools.ico") def interface(self): # 用局部变量存储按钮(或直接创建无需存储),避免覆盖self上的其他属性 btnopen = tk.Button(self.root, text="open child window", command=self.onclick).pack() def onclick(self): window = tk.Toplevel() window.geometry('200x100+500+250') window.title('child window') # 用lambda直接传递window给test方法 btnclick = tk.Button(window, text="click", command=lambda: self.test(window)).pack() # 补充:这里的window.mainloop()是多余的,主窗口的事件循环已经会管理顶级窗口 # window.mainloop() def test(self, window): window.iconify() # 若需要可恢复窗口显示 # window.deiconify() if __name__ == '__main__': gui = GUI() gui.root.mainloop()
内容的提问来源于stack exchange,提问作者missmango
相关产品推荐
相关产品推荐

