我的意思是你可以通過將 mainloop() 函式放在 for 回圈或 while 回圈中來使程式多次打開視窗嗎?它可能看起來像這樣:
for i in range(n):
window.mainloop()
或者,如果我們使用 while 回圈:
i = 0
while i < n:
window.mainloop()
當我嘗試其中任何一種方法時,它只會打開一個視窗。我做錯了什么還是 mainloop() 是一個不能放入回圈的函式?如果是這樣,還有其他方法嗎?
uj5u.com熱心網友回復:
mainloop多次呼叫無法打開新視窗。mainloop只處理事件,它不會創建或重新創建任何視窗。
如果您需要多個視窗,方法是Toplevel為第二個和后續視窗創建實體。然后,您只需呼叫mainloop一次,所有視窗都將可見,假設它們已設定為可見。
如果你想創建同一個視窗的多個實體,通常的模式是在一個繼承自Frame. 然后,您可以根據需要創建任意數量的視窗,并且可以在每個視窗中創建該框架的實體。
這是該技術的一個示例:
import tkinter as tk
class App(tk.Frame):
def __init__(self, parent, *args, **kwargs):
super().__init__(parent, *args, **kwargs)
self.count = 0
self.button = tk.Button(self, text="Click me!", command=self.click)
self.label = tk.Label(self, text="", width=20)
self.label.pack(side="top", fill="both", expand=True)
self.button.pack(side="bottom", padx=4, pady=4)
self.refresh_clicks()
def click(self):
self.count = 1
self.refresh_clicks()
def refresh_clicks(self):
self.label.configure(text=f"Clicks: {self.count}")
apps = []
n = 5
for i in range(n):
window = tk.Tk() if i == 0 else tk.Toplevel()
app = App(window)
app.pack(fill="both", expand=True)
apps.append(app)
tk.mainloop()
請務必注意,如果您洗掉第一個視窗,則所有其他視窗都將被洗掉。如果您不希望這種情況發生,您可以創建然后隱藏根視窗,以便用戶只能看到其他視窗。然后,當不再有任何子視窗時,您需要添加一些代碼來終止根視窗。
uj5u.com熱心網友回復:
內部的正常方法tkinter是在一個“主回圈”中運行所有視窗。你也可以在單獨的行程中運行一個主回圈,每個行程都可以獨立運行一個主回圈。
另一個答案現在有一個“在一個主回圈內”方式的示例 - 也許稍后我將在我自己的示例中進行編輯。
這是一個如何在單獨的行程中運行“mainloop”的最小示例:
import multiprocessing
import tkinter
# Note, due to a quirk of multprocessing and pickle,
# you can't just copy-paste this in the interactive
# Python REPL, it has to go in a file.
def ui():
tkinter.Tk().mainloop()
if __name__ == '__main__':
multiprocessing.Process(target=ui).start()
# The above line did not block, because mainloop
# ran in another process. So now we can run more
# mainloops in parallel if we want:
multiprocessing.Process(target=ui).start()
我不會這樣做,除非每個視窗都是它自己的獨立應用程式,由于某種原因恰好從一個父行程啟動,或者你有其他非常好的理由來隔離它。
至于為什么它不起作用:
window.mainloop是一個阻塞/持續的操作 - 它通過在名稱中包含“回圈”來暗示這一點 - 在該函式內部是所謂的“事件回圈”,代碼只是位于該回圈中等待和處理視窗事件,直到視窗已經關了。
你幾乎可以這樣想:
def mainloop():
while window_exists:
...
# this is why it doesn't work
# it loops forever in here
for i in range(n):
mainloop()
有關更多詳細資訊,您可以深入了解tkinter檔案,您可以在其中找到類似的解釋:
Tcl/Tk 應用程式通常是事件驅動的,這意味著在初始化之后,解釋器會運行一個事件回圈 [...] 這與許多 GUI 工具包不同,在這些工具包中,GUI 在與所有應用程式代碼(包括事件處理程式)完全分離的執行緒中運行。
原則上,多個執行緒或行程可以各自運行一個事件回圈,但在這種情況下,tkinter假設 Tcl(以及因此 Tk)沒有使用執行緒安全(排除執行緒)進行編譯。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/492002.html
上一篇:從使用輸入的類中獲取變數
