簡體   English   中英

為什么 tk object 的屬性被“追溯”更改?

[英]Why are attributes of a tk object being 'retroactively' changed?

個人項目,我認為能夠創建一個在 windows 之間有很多關系的人會很酷,所以當“父母”window 關閉時,它的所有“孩子”也都關閉了。

所以這是 window class,它通過 Tk() function 創建新的 windows:

from tkinter import *

class Window:
    def __init__(self, title):
        self.create(title)

    def create(self,title):
        self.window = Tk()
        self.window.title(title)
        self.window.protocol("WM_DELETE_WINDOW",self.delete)

    def child(self, title):
        self.create(title)

    def delete(self):
        print(f'Destroying: {self.window.title()}')
        self.window.destroy()


parentclass1 = Window("ParentClass1")
parentclass2 = Window("ParentClass2")
parentclass3 = Window("ParentClass3")

print(parentclass1.window.title())
print(parentclass2.window.title())
print(parentclass3.window.title())
mainloop()

這很好用。 每個 window 打開,當查詢其標題時,每個實例返回正確的標題:

print(parentclass1.window.title()) #=\> "ParentClass1"
print(parentclass2.window.title()) #=\> "ParentClass2"
print(parentclass3.window.title()) #=\> "ParentClass3"

我希望能夠做的是在 parentclass2 實例上調用 child 方法,並立即在 parentclass2 和新創建的實例之間建立關系。 即parentclass2是parent,新創建的實例是parentclass2的child。

然而,在我什至通過數組建立這種關系之前,當我使用子方法時發生了一件非常奇怪的事情:

parentclass2.child("ChildOfParentClass2")

print(parentclass1.window.title()) #=> "ParentClass1"
print(parentclass2.window.title()) #=> "ChildOfParentClass2"
print(parentclass3.window.title()) #=> "ParentClass1"

parentclass2.window.title() 現在返回字符串“ChildOfParentClass2”。

這很奇怪。 self.window = Tk() 顯然分別被調用了兩次,但不知何故設置“ChildOfParentClass2”的標題是“在堆棧中上升”並將 ParentClass2 重命名為 ChildOfParentClass2?

我不認為是 the.title 方法在做這件事。 我認為 parentclass2.window 從字面上看變成了 childofparentclass2.window。

我知道 tkinter 的行為很奇怪,因為我試圖將它強加到我的 object 導向方法中......但以這種方式使用它會很酷,所以希望得到答案。

任何人都可以解釋這種奇怪的行為,也許可以解決它,我將能夠調用 parentclass2.child("ChildOfParentClass2") 並讓它按預期工作嗎?

我試過在 child 中使用 Toplevel() 並在 init 中使用 Tk() 但發生了完全相同的奇怪行為:

def __init__(self, title):
    self.window = Tk()
    self.create(title)

def create(self,title):
    self.window.title(title)
    self.window.protocol("WM_DELETE_WINDOW",self.delete)

def child(self, title):
    self.window = Toplevel() # thought this would work tbh
    self.create(title)

奇怪行為的原因是,在create中,您將self.window重新定義為新創建的 window。它不再代表原始 window。因此,當您打印您認為是主要 window 的標題時,您實際上是打印孩子的名字 window。

如果要創建根 window 的子節點,則需要創建Toplevel的實例。 然后,您可以將根 window 作為Toplevel的 master 傳入,以創建父/子關系。

def child(self, title):
    new_window = Toplevel(master=self.window)
    new_window.title(title)

當你這樣做時,孩子 windows 將在父母去世時自動刪除。 您根本不需要做任何事情來實現這一點,這是 tkinter 小部件的默認行為。

請記住,如果您創建了多個Tk實例,則每個實例都是相互隔離的。 圖像、變量、fonts 和在一個中創建的其他小部件無法與另一個進行通信或移動到另一個。 每個都有自己獨立的內部 tcl 解釋器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM