当您单击并拖动鼠标时,我有一个可以自动调整大小的窗口。问题是从右向左拖动时,窗口的右侧会跳来跳去。这个问题只发生在Windows而不是Linux上,我不确定MaxOS,因为我没有访问运行它的计算机的权限。 有人知道如何解决这个问题吗?
更新:我已经根据下面建议的“ jizhihaoSAMA”更新了代码,现在可以在Windows和Linux上正常使用,仍然不确定MacOS!
import tkinter as tk
import tkinter.ttk as ttk
import tkinter.font as tkfont
from sys import platform
class Selector(tk.Toplevel):
def __init__(self, parent, **kwargs):
super().__init__(parent, **kwargs)
self.geometry('0x0+0+0')
self.overrideredirect(True)
if platform == 'linux':
self.wait_visibility(self)
self.wm_attributes('-alpha', 0.2)
self.wm_attributes("-topmost", True)
self.config(bg='#00aaff')
self.update()
self.lift()
self.linespace = self.master.linespace
self.heading_padding = parent.style.lookup('Treeview.Heading', 'padding')
self.theme = parent.style.theme_use()
self.style = parent.style
def select(self, _):
widget = self.focus_get()
master = widget.winfo_toplevel()
if widget == master:
return
padding = 0 if not isinstance(widget, ttk.Treeview) else \
int(str(self.style.lookup('Treeview.Heading', 'padding')[0]))
tv_padding = padding*2 if isinstance(widget, ttk.Treeview) else 0
border_width = 3 if self.theme == 'default' else 6
linespace = self.linespace if isinstance(widget, ttk.Treeview) else 0
x, y = master.winfo_pointerxy()
root_x = widget.winfo_rootx()
root_y = widget.winfo_rooty()+linespace+tv_padding+border_width
wdg_width = widget.winfo_width()
wdg_height = widget.winfo_height()-linespace-tv_padding-border_width
if x < root_x:
x = root_x
elif x > root_x + widget.winfo_width():
x = root_x + wdg_width
if y < root_y:
y = root_y
elif y > root_y + wdg_height:
y = root_y + wdg_height
origin_x = widget.origin_x if x > widget.origin_x else x
origin_y = widget.origin_y if y > widget.origin_y else y
self.geometry(f'{abs(x-widget.origin_x)}x{abs(y-widget.origin_y)}+{origin_x}+{origin_y}')
class App(tk.Tk):
def __init__(self):
super().__init__()
self.rowconfigure(0, weight=1)
self.rowconfigure(1, weight=1)
self.columnconfigure(0, weight=1)
self.columnconfigure(1, weight=1)
self.title('Selector Demo')
font = tkfont.nametofont('TkDefaultFont')
self.linespace = font.metrics('linespace')
self.style = ttk.Style()
self.style.theme_use('clam')
self.style.configure('Treeview.Heading', padding=5)
self.style.configure('Treeview', rowheight=self.linespace+7)
self.selector = Selector(self)
var = tk.StringVar()
var.set(('List Item 1', 'List Item 2', 'List Item 3', 'List Item 4', 'List Item 5'))
self.lb = tk.Listbox(self, listvariable=var, selectmode=tk.EXTENDED, width=50, height=15)
self.lb.grid(padx=20, pady=20, row=0, column=0)
tree = ttk.Treeview(self)
tree["columns"] = ("one", "two", "three")
tree.column("#0", width=120, minwidth=3, stretch=tk.NO)
tree.column("one", width=150, minwidth=3, stretch=tk.NO)
tree.column("two", width=80, minwidth=3)
tree.column("three", width=80, minwidth=50, stretch=tk.NO)
tree.heading("#0", text="Name", anchor=tk.W)
tree.heading("one", text="Date modified", anchor=tk.W)
tree.heading("two", text="Type", anchor=tk.W)
tree.heading("three", text="Size", anchor=tk.W)
# Level 1
folder1 = tree.insert("", 1, text="Folder 1", open=1, values=("23-Jun-17 11:05", "File folder", ""))
tree.insert("", 2, text="text_file.txt", values=("23-Jun-17 11:25", "TXT file", "1 KB"))
# # Level 2
tree.insert(folder1, "end", text="photo1.png", values=("23-Jun-17 11:28", "PNG file", "2.6 KB"))
tree.insert(folder1, "end", text="photo2.png", values=("23-Jun-17 11:29", "PNG file", "3.2 KB"))
tree.insert(folder1, "end", text="photo3.png", values=("23-Jun-17 11:30", "PNG file", "3.1 KB"))
tree.grid(padx=20, pady=20, row=0, column=1)
self.tb = tk.Text(self, height=10)
self.tb.grid(pady=(0, 20), columnspan=2)
self.tb.insert(tk.END, "Just a text Widget\nin two lines\n")
self.tb.cursor = self.tb.cget('cursor')
self.bind('<Button-1>', self.button_press)
self.bind('<ButtonRelease-1>', self.button_release)
def button_press(self, event):
wdg = event.widget
wdg.focus_set()
if isinstance(wdg, tk.Text):
wdg.config(cursor='arrow')
self.selector.geometry('0x0+0+0')
wdg.origin_x, wdg.origin_y = wdg.winfo_pointerxy()
self.bind('<Motion>', self.selector.select)
def button_release(self, event):
wdg = event.widget
if isinstance(wdg, tk.Text) and hasattr(wdg, 'cursor'):
wdg.config(cursor=wdg.cursor)
self.selector.geometry('0x0+0+0')
self.unbind('<Motion>')
def main():
app = App()
app.mainloop()
if __name__ == '__main__':
main()