我知道如果我想创建一个没有标题栏的窗口,可以这样写:
root = Tk()
........
root.overrideredirect(1)
但我也希望窗口可以调整大小。有什么解决方案吗?
(FYI:我正在Windows电脑上工作,虽然我不确定这是否真的重要。如果有一个独立于操作系统的解决方案,那将是完美的,但如果至少有一个Windows的解决方案,我也很高兴。)
我知道如果我想创建一个没有标题栏的窗口,可以这样写:
root = Tk()
........
root.overrideredirect(1)
但我也希望窗口可以调整大小。有什么解决方案吗?
(FYI:我正在Windows电脑上工作,虽然我不确定这是否真的重要。如果有一个独立于操作系统的解决方案,那将是完美的,但如果至少有一个Windows的解决方案,我也很高兴。)
问题是,窗口可以被调整大小,但当您打开overrideredirect
时,您将失去任何可以用于调整窗口大小的标题栏或边缘。唯一的解决方法是自己实现调整大小。您可以添加自己的边框,或者添加当鼠标靠近边缘时起作用的鼠标绑定。
这个答案展示了如何移动这样的窗口:Python/Tkinter: Mouse drag a window without borders, eg. overridedirect(1)
这里有一个简短的例子,说明如何调整大小。它只在OSX上进行了基本测试,但应该适用于任何平台。它使用python2,但通过更改导入语句,应该可以与python3一起使用。
import Tkinter as tk
import ttk
class Example(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.floater = FloatingWindow(self)
class FloatingWindow(tk.Toplevel):
def __init__(self, *args, **kwargs):
tk.Toplevel.__init__(self, *args, **kwargs)
self.overrideredirect(True)
self.wm_geometry("400x400")
self.label = tk.Label(self, text="Grab the lower-right corner to resize")
self.label.pack(side="top", fill="both", expand=True)
self.grip = ttk.Sizegrip(self)
self.grip.place(relx=1.0, rely=1.0, anchor="se")
self.grip.lift(self.label)
self.grip.bind("<B1-Motion>", self.OnMotion)
def OnMotion(self, event):
x1 = self.winfo_pointerx()
y1 = self.winfo_pointery()
x0 = self.winfo_rootx()
y0 = self.winfo_rooty()
self.geometry("%sx%s" % ((x1-x0),(y1-y0)))
return
app=Example()
app.mainloop()
这里可以找到@Bryan解决方案的扩展工作示例:
import tkinter as tk
class FloatingWindow(tk.Tk):
def __init__(self):
super().__init__()
self.overrideredirect(True)
self.center()
self.label = tk.Label(self, text="Grab one of the blue")
self.label.pack(side="top", fill="both", expand=True)
self.grip_se = tk.Label(self,bg='blue')
self.grip_se.place(relx=1.0, rely=1.0, anchor="se")
self.grip_se.bind("<B1-Motion>",lambda e, mode='se':self.OnMotion(e,mode))
self.grip_e = tk.Label(self,bg='green')
self.grip_e.place(relx=1.0, rely=0.5, anchor="e")
self.grip_e.bind("<B1-Motion>",lambda e, mode='e':self.OnMotion(e,mode))
self.grip_ne = tk.Label(self,bg='blue')
self.grip_ne.place(relx=1.0, rely=0, anchor="ne")
self.grip_ne.bind("<B1-Motion>",lambda e, mode='ne':self.OnMotion(e,mode))
self.grip_n = tk.Label(self,bg='green')
self.grip_n.place(relx=0.5, rely=0, anchor="n")
self.grip_n.bind("<B1-Motion>",lambda e, mode='n':self.OnMotion(e,mode))
self.grip_nw = tk.Label(self,bg='blue')
self.grip_nw.place(relx=0, rely=0, anchor="nw")
self.grip_nw.bind("<B1-Motion>",lambda e, mode='nw':self.OnMotion(e,mode))
self.grip_w = tk.Label(self,bg='green')
self.grip_w.place(relx=0, rely=0.5, anchor="w")
self.grip_w.bind("<B1-Motion>",lambda e, mode='w':self.OnMotion(e,mode))
self.grip_sw = tk.Label(self,bg='blue')
self.grip_sw.place(relx=0, rely=1, anchor="sw")
self.grip_sw.bind("<B1-Motion>",lambda e, mode='sw':self.OnMotion(e,mode))
self.grip_s = tk.Label(self,bg='green')
self.grip_s.place(relx=0.5, rely=1, anchor="s")
self.grip_s.bind("<B1-Motion>",lambda e, mode='s':self.OnMotion(e,mode))
def OnMotion(self, event, mode):
abs_x = self.winfo_pointerx() - self.winfo_rootx()
abs_y = self.winfo_pointery() - self.winfo_rooty()
width = self.winfo_width()
height= self.winfo_height()
x = self.winfo_rootx()
y = self.winfo_rooty()
if mode == 'se' and abs_x >0 and abs_y >0:
self.geometry("%sx%s" % (abs_x,abs_y)
)
if mode == 'e':
if height >0 and abs_x >0:
self.geometry("%sx%s" % (abs_x,height)
)
if mode == 'ne' and abs_x >0:
y = y+abs_y
height = height-abs_y
if height >0:
self.geometry("%dx%d+%d+%d" % (abs_x,height,
x,y))
if mode == 'n':
height=height-abs_y
y = y+abs_y
if height >0 and width >0:
self.geometry("%dx%d+%d+%d" % (width,height,
x,y))
if mode == 'nw':
width = width-abs_x
height=height-abs_y
x = x+abs_x
y = y+abs_y
if height >0 and width >0:
self.geometry("%dx%d+%d+%d" % (width,height,
x,y))
if mode == 'w':
width = width-abs_x
x = x+abs_x
if height >0 and width >0:
self.geometry("%dx%d+%d+%d" % (width,height,
x,y))
if mode == 'sw':
width = width-abs_x
height=height-(height-abs_y)
x = x+abs_x
if height >0 and width >0:
self.geometry("%dx%d+%d+%d" % (width,height,
x,y))
if mode == 's':
height=height-(height-abs_y)
if height >0 and width >0:
self.geometry("%dx%d+%d+%d" % (width,height,
x,y))
def center(self):
width = 300
height = 300
screen_width = self.winfo_screenwidth()
screen_height = self.winfo_screenheight()
x_coordinate = (screen_width/2) - (width/2)
y_coordinate = (screen_height/2) - (height/2)
self.geometry("%dx%d+%d+%d" % (width, height,
x_coordinate, y_coordinate))
app=FloatingWindow()
app.mainloop()
输出:
如果有人知道如何解决性能问题,请回答这个问题。
win.resizable(False,True)
和win.resizable(True, False)
会创建可在两个方向上调整大小的窗口。 - saulspatz