本文介绍了高水平的Tkinter定制的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我想完全定制我的应用程序,所以我创建了一个标题栏,并想出了一种拖动它的方法,但现在我的问题是它缺乏一些功能,比如调整大小和各种动画,我在想,是否有可能通过一些库来摆脱标题栏?或者可以恢复部分功能,使我不必在每次想要隐藏窗口时使用OverridereDirect?第一个选项更好,但我确实使用了ctypes.windll
将窗口放回任务栏,但它似乎也不是最实用的解决方案。
到目前为止,代码如下所示:
import tkinter as tk
from ctypes import windll
GWL_EXSTYLE = -20
WS_EX_APPWINDOW = 0x00040000
WS_EX_TOOLWINDOW = 0x00000080
WS_BORDER = 0x00800000
class Application(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.overrideredirect(True)
self.after(10, self.setup_window)
self.geometry('1000x500+500+250')
self.app_hidden = False
self.bind('<Expose>', self.show_app)
# for full customization im using different widgets as buttons
# lets assume its on the custom title bar
text = tk.Label(self, width=10, height=2,
bg='blue', text='close', foreground='white')
text.pack()
text.bind('<ButtonPress-1>', self.hide_app)
# taken from another post
def setup_window(self, t: int = 10):
hwnd = windll.user32.GetParent(self.winfo_id())
style = windll.user32.GetWindowLongPtrW(hwnd, GWL_EXSTYLE)
style = style & ~WS_EX_TOOLWINDOW
style = style | WS_EX_APPWINDOW
res = windll.user32.SetWindowLongPtrW(hwnd, GWL_EXSTYLE, style)
self.wm_withdraw()
self.after(t, self.wm_deiconify)
def hide_app(self):
if not self.app_hidden:
self.overrideredirect(False)
self.iconify()
self.app_hidden = True
def show_app(self, event):
if self.app_hidden:
self.overrideredirect(True)
self.setup_window()
self.app_hidden = False
if __name__ == '__main__':
app = Application()
app.mainloop()
我想要的是能够返回边界,IV‘e尝试通过添加
WS_BORDER = 0x00800000
...
def setup_window(self):
...
style = style | WS_BORDER
...
但它不起作用,我也希望不存在已经存在的不必要的绑定,所以主要问题是,如果有一些库能够在高级上与默认的Windows管理器交互,那么是否有可能在没有overrideredirect
的情况下overrideredirect
?
推荐答案
正如我在我的评论中所说,据我所知,这项工作对你有什么好处是没有延期的。您必须自己进行窗口管理。不管怎样,你可能想要这样的东西:
import win32con
import win32api
import win32gui
import tkinter as tk
def override(event):
hwnd = win32gui.GetParent(root.winfo_id())
style= win32api.GetWindowLong(hwnd, win32con.GWL_STYLE)
style&= ~win32con.WS_MINIMIZEBOX
style&= ~win32con.WS_MAXIMIZEBOX
style&= ~win32con.WS_SYSMENU
style&= ~win32con.WS_CAPTION
#style&= ~win32con.WS_SIZEBOX
valid= win32api.SetWindowLong(hwnd, win32con.GWL_STYLE, style)
root.bind('<Map>', None)
root = tk.Tk()
root.bind('<Map>', override)
root.mainloop()
如果使用这些选项,您可以获得各种窗口样式,如下所示。
WS_MINIMIZEBOX:
WS_MAXIMIZEBOX:
WS_MINIMIZEBOX&;WS_MAXIMIZEBOX:
WS_SYSMENU:
WS_CAPTION:
WS_Caption&;SIZEBOX:
CTYPE解决方案
import tkinter as tk
from ctypes import windll, wintypes
GWL_STYLE = -16
WS_SYSMENU = 0x00080000
SWP_FRAMECHANGED = 0x0020
SWP_NOACTIVATE = 0x0010
SWP_NOMOVE = 0x0002
SWP_NOSIZE = 0x0001
GetWindowLong = windll.user32.GetWindowLongW
SetWindowLong = windll.user32.SetWindowLongW
SetWindowPos = windll.user32.SetWindowPos
class App(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.hwnd = int(self.wm_frame(), 16)
tk.Button(self, text="Remove buttons", command=self.remove_buttons).pack()
tk.Button(self, text="Add buttons", command=self.add_buttons).pack()
def remove_buttons(self):
old_style = GetWindowLong(self.hwnd, GWL_STYLE)
new_style = old_style & ~WS_SYSMENU
SetWindowLong(self.hwnd, GWL_STYLE, new_style)
SetWindowPos(self.hwnd, 0, 0,0,0,0, SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE)
def add_buttons(self):
old_style = GetWindowLong(self.hwnd, GWL_STYLE)
new_style = old_style | WS_SYSMENU
res = SetWindowLong(self.hwnd, GWL_STYLE, new_style)
res = SetWindowPos(self.hwnd, 0, 0,0,0,0, SWP_FRAMECHANGED | SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE)
if __name__ == "__main__":
app = App()
app.mainloop()
这篇关于高水平的Tkinter定制的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!