基于這個問題,我寫了以下mwe:
import tkinter as tk
class BaseFrame(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.parent = parent
self.bmanage = tk.Button(self, text='undock', command = self.undock)
self.bforget = tk.Button(self, text='dock', command = self.dock)
self.bmanage.grid(row=0, column=0, padx=20, pady=20, sticky='nsew')
self.bforget.grid(row=0, column=1, padx=20, pady=20, sticky='nsew')
self.dockable_frame = tk.Frame(self, bg="red", height=100)
self.dockable_frame.grid(row=1, column=0, padx=20, pady=20, columnspan=2, sticky='nsew')
self.label = tk.Label(self.dockable_frame, text="hi")
self.label.grid(row=0, column=0, padx=150, pady=20, sticky='nsew')
def undock(self):
self.parent.wm_manage(self.dockable_frame)
self.dockable_frame.configure(bg='blue')
print(type(self.dockable_frame))
def dock(self):
self.parent.wm_forget(self.dockable_frame)
self.dockable_frame.grid()
if __name__ == "__main__":
root = tk.Tk()
base_frame = BaseFrame(root)
base_frame.grid(row=0, column=0, padx=20, pady=20, sticky='nsew')
root.mainloop()
單擊取消停靠按鈕,取消停靠紅框,單擊停靠按鈕,再次停靠該框。我有兩個問題:
- 為什么 self.dockable_frame 的型別是<class 'tkinter.Frame'>而不是 TopLevel 因為wm 管理檔案說:指定的小部件將成為獨立的頂級視窗?
- 由于self.dockable_frame.protocol("WM_DELETE_WINDOW", insert_function_here)在我的 Windows 電腦上出現錯誤,我該如何處理視窗關閉事件?
錯誤是:
AttributeError: 'Frame' object has no attribute 'protocol'
我理解錯誤,但如何處理視窗關閉事件?
uj5u.com熱心網友回復:
為什么 self.dockable_frame 的型別是 <class 'tkinter.Frame'> 而不是 TopLevel,因為 wm 管理檔案說:指定的小部件將成為獨立的頂級視窗?
我認為這是因為self.dockable_frame是一個 python 類并且不知道底層小部件已更改。可以說這是wm_manage.
由于 self.dockable_frame.protocol("WM_DELETE_WINDOW", insert_function_here) 在我的 Windows PC 上出現錯誤,我該如何處理視窗關閉事件?
最簡單的方法是直接從tk.Wm類中呼叫方法。它看起來像這樣:
tk.Wm.protocol(self.dockable_frame, "WM_DELETE_WINDOW", self.whatever)
uj5u.com熱心網友回復:
該檔案具有誤導性。當我發現這個我認為類似的功能時,框架變成了一個視窗。事實上,這不是真的,我可以通過下面的代碼證明這一點。
真正發生的事情,至少在 MS-Windows 下,但我希望在其他作業系統下具有相同的功能,即幀將被打包在 wm_mange 為此創建的不同頂層上。
當 tkinter 定義一個Window/Toplevel 時,它總是為您將使用的客戶區構建一個子視窗(框架)。這就是為什么你需要呼叫 win32gui。當您將更改視窗樣式時,請使用GetParent方法。
代碼:
import tkinter as tk
import win32gui
def info():
print(f'python id: {id(frame)}')
print(f'tkinterID: {frame.winfo_id()}')
print(f'parent id: {win32gui.GetParent(frame.winfo_id())}')
def undock():
root.wm_manage(frame)
def forget():
root.wm_forget(frame)
frame.pack()
root = tk.Tk()
frame= tk.Frame()
frame.pack()
b1 = tk.Button(frame,text='INFO',command=info)
b2 = tk.Button(frame,text='mnge',command=undock)
b3 = tk.Button(frame,text='nrml',command=forget)
b1.pack()
b2.pack()
b3.pack()
root.mainloop()
輸出:
通過第一次出現:
python id: 67118160
tkinterID: 3412074
parent id: 7867926
脫離后
python id: 67118160
tkinterID: 3412074
parent id: 15666896
忘記之后
python id: 67118160
tkinterID: 3412074
parent id: 7867926
參考:
In Tk, Toplevel windows are basically a special form of a Frame which are managed by the window manager. The proposal is to add the commands wm manage and wm forget which will take an arbitrary Frame and allow it to be managed by the window manager, making it a Toplevel window.
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/358525.html
