1.问题发现:
众所周知,原生tkinter无法高自由度编辑窗口标题栏。所以我们想用好看的标题栏时不得不隐藏自带的标题栏,然后重新设计自己想要的标题栏。
隐藏标题栏最常用的办法就是overrideredirect(True),但是用这个办法最致命的一个问题就是无法把窗口变成最小化,也就是root.iconify()无法使用。如图所示
可能原因是在没有标题栏的情况下,Tkinter 不会再自动为你管理窗口的最小化、最大化和关闭状态。
Exception in Tkinter callback
Traceback (most recent call last):
File "c:\Users\Administrator\AppData\Local\Programs\Python\Python311\Lib\tkinter\__init__.py", line 1948, in __call__
return self.func(*args)
^^^^^^^^^^^^^^^^
File "D:\Decktop\PyMe1.4.8.7\Project1\demo.py", line 9, in Window_iconic
root.iconify()
File "c:\Users\Administrator\AppData\Local\Programs\Python\Python311\Lib\tkinter\__init__.py", line 2142, in wm_iconify
return self.tk.call('wm', 'iconify', self._w)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_tkinter.TclError: can't iconify ".": override-redirect flag is set
2.解决办法
这个可能不是最优的解决办法,但是简单易懂的。实现思路就是监听窗口状态、监听窗口最大化,最小化,正常模式触发的函数。
源代码这样
import tkinter as tk
root=tk.Tk()
root.geometry("200x200")
#自定义按钮最小化绑定的函数
def Window_iconic():
root.overrideredirect(False)
root.iconify()
#监听窗口最大化或者正常模式的绑定事件
def Window_normal(event):
if root.state() == "normal" or root.state() == "zoomed":
root.overrideredirect(True)
btn = tk.Button(root, text="最小化", command=Window_iconic)#假装这个是一个自定义状态栏的最小化按钮
root.bind("<Configure>", Window_normal) #窗口变化监听按钮
btn.pack()
root.mainloop()
1 - 最小化按钮的实现思路:
** 用户按下最小化按钮的瞬间窗口恢复有标题栏的状态。并最小化。因为速度很快(这个也得看电脑的性能吧)肉眼看不见状态变化。顶多看见屏幕闪一下。
2 - 窗口恢复无标题栏实现的思路
** 用户按下下方任务栏程序图标的同时能监听窗口恢复到正常(normal)或最大化(zoomed),随后马上变成无标题栏模式
免责声明:此办法能有效解决tkinter无标题栏状态下无法最小化的毛病。但不是最优办法。如果找到比这个更好的办法可以优先使用该办法。其次这个办法有状态变化时闪烁几下的毛病,完美主义者和强迫症谨慎使用。