Python 3.x Tkinter一次移动两个小部件
为什么如果我创建两个小部件,它就会停止工作? 我的主框架循环:Python 3.x Tkinter一次移动两个小部件,python-3.x,tkinter,Python 3.x,Tkinter,为什么如果我创建两个小部件,它就会停止工作? 我的主框架循环: import tkinter as tk class LobbyGUI(tk.Frame): def __init__(self): self.main_window = tk.Tk() self.x = 200 self.y = 200 self.height = 500 self.width = 900 self.mai
import tkinter as tk
class LobbyGUI(tk.Frame):
def __init__(self):
self.main_window = tk.Tk()
self.x = 200
self.y = 200
self.height = 500
self.width = 900
self.main_window.geometry(f"{self.width}x{self.height}+{self.x}+{self.y}")
super(LobbyGUI, self).__init__(self.main_window)
self.pack()
self.main_window.update_idletasks()
self.widgets = dict()
self.widgets['search'] = SearchWindow(self.main_window)
self.widgets['search2'] = SearchWindow(self.main_window)
self.main_window.bind("<Configure>", self.on_drag)
def mainloop(self, n=0):
while True:
self.update_idletasks()
self.update()
def on_drag(self, event):
for widget in self.widgets.values():
widget.place()
它适用于一个子搜索窗口,但不适用于两个子搜索窗口。这种方法哪里会有问题?好的,几个小时后我成功了。 我们需要做的就是从映射到
的其他事件中过滤主帧位置的实际变化。这可能不是一个有效的方法,但至少它起作用了:
解决方案1:
为什么要创建自己的
mainloop
?它的效率将大大低于真正的主循环。@BryanOakley为什么会这样?遵循这一点,它们在概念上是相等的,但它们并不相等。真正的mainloop
比仅仅调用update
要做更多的工作。您所指的答案实际上很好地解释了为什么在坏循环中调用update
和update\u idletasks
。@BryanOakley您可能是对的。我将检查源代码以完全理解其中的差异。@BryanOakley我已设法在两次.lift()
调用中发现问题。你有办法解决这个问题吗?
class SearchWindow:
def __init__(self, root):
self.root = root
self.top = tk.Toplevel(root)
self.width = 100
self.height = 20
self.top.geometry(f"{self.width}x{self.height}+0+0")
self.place()
self.top.overrideredirect(1) # remove title border
self.entry = tk.Entry(master=self.top, width=self.width, borderwidth=0, highlightthickness=0)
self.entry.pack()
def place(self):
x = self.root.winfo_rootx()
y = self.root.winfo_rooty()
width = self.root.winfo_width()
self.top.geometry(f"+{x + width - self.width - 50}+{y + 20}")
self.top.lift()
class LobbyGUI:
def __init__(self):
self.main_window = tk.Tk()
self.x = 200
self.y = 200
self.height = 500
self.width = 900
self.geometry = f"{self.width}x{self.height}+{self.x}+{self.y}"
self.main_window.geometry(self.geometry)
self.widgets = dict()
self.widgets['search'] = SearchWindow(self.main_window)
self.widgets['search2'] = SearchWindow(self.main_window)
self.main_window.bind("<Configure>", self.on_drag)
def on_drag(self, event):
for widget in self.widgets.values():
widget.place()
if self.geometry != self.main_window.geometry():
for widget in self.widgets.values():
widget.lift(aboveThis=self.main_window)
self.geometry = self.main_window.geometry()
def start(self):
self.main_window.mainloop()
class SearchWindow(tk.Toplevel):
def __init__(self, root):
super(SearchWindow, self).__init__(root)
self.root = root
self.width = 100
self.height = 20
self.geometry(f"{self.width}x{self.height}+0+0")
# self.top.overrideredirect(1) # remove title border
self.entry = tk.Entry(master=self, width=self.width, borderwidth=0, highlightthickness=0)
self.entry.pack()
self.place()
def place(self):
x = self.root.winfo_rootx()
y = self.root.winfo_rooty()
width = self.root.winfo_width()
self.geometry(f"+{max(x + width - self.width - 50, 0)}+{y + 20}")
def mainloop(self):
while 1:
self.main_window.update()
for widget in self.widgets.values():
widget.lift(aboveThis=self.main_window)
self.main_window.update_idletasks()