簡體   English   中英

如何在 Tkinter 中獲取小部件的名稱?

[英]How can I get the name of a widget in Tkinter?

我有一系列按鈕的通用回調。 調用回調后,我想通過先前分配的名稱來識別調用者。 但是我無法在 Tkinter 文檔中弄清楚如何做到這一點。 有任何想法嗎?

我的程序大約是。

def callback(event):
    event.widget['text'] # 'name' does not work so 
                         # I have to use the label of the button now, but it is a dirty solution.

root.bind("<Button-1>", cb_button)

我需要名稱,因為我使用pytkgen從 JSON 加載 GUI。

更新:
Justin 的解決方案看起來不錯,但為什么無論單擊哪個按鈕,以下代碼總是打印9

def cb_button(i):
    print i

buttons = [('btn'+str(i), i) for i in range(10)]
for (b, i) in buttons:
    root.button(b, lambda: cb_button(i))

小部件的 winfo_name() 方法返回小部件的名稱。 通常是用字符串表示的 8 位數字,即:'40123211' 如果您有事件對象 evt,則使用:evt.widget.winfo_name()

在問題的正文中,您要問一些不同的問題:“如何判斷哪個按鈕調用了通用回調函數”

使用 lambda 函數將唯一值傳遞給公共回調:

根據對您問題的更新,我想我明白了這個問題。 您有一個用於通過 pytkgen 創建 Tkinter 接口的 JSON 文件。 在這個 JSON 文件中有幾個按鈕的定義,每個按鈕都有一個唯一的名稱。 將命令分配給這些按鈕時,它們都會得到相同的回調,但回調需要知道哪個按鈕發起了調用,而您希望通過名稱來實現。 那是對的嗎?

如果是這樣,我猜您當前正在創建這樣的回調分配(非常通用的示例,假設root是通過使用 JSON 文件的路徑調用tkgen.gengui.TkJson返回的接口根):

root.button("name1", callback)
root.button("name2", callback)
...

但是,這並沒有給你你想要的名字。 傳遞名稱的一種方法是創建一個lambda ,將按鈕名稱傳遞給回調函數。 回調分配看起來像這樣:

root.button("name1", lambda:callback("name1"))
root.button("name2", lambda:callback("name2"))
...

那么您的回調定義可能如下所示:

def callback(name):
    if name == "name1":
        # Do something in here
    elif name == "name2":
        # Do something else in here
    ...

更新:如果您在循環內創建按鈕,則需要修改 lambda 定義以將所需的循環變量存儲為關鍵字默認值。 否則,循環變量的最終值將應用於所有按鈕。

def cb_button(i):
    print i

buttons = [('btn'+str(i), i) for i in range(10)]
for (b, i) in buttons:
    root.button(b, lambda x=i: cb_button(x))

向小部件對象添加屬性

另一種解決方案是可以在回調函數中檢查按鈕小部件對象的屬性。 (此示例使用 Tkinter)

but1 = Tkinter.Button(root, text="Sync", width=10)
but1.bind("<Button-1>", doButton)
but1.myId = "this"

but2 = Tkinter.Button(root, text="Sync", width=10)
but2.bind("<Button-1>", doButton)
but2.myId = "that"
but2.otherStuff = "anything"

def doButton(evt):
  if evt.widget.myId == "this":
    print("This")
  else:
    print("That "+evt.widget.otherStuff)

我不記得如何獲得名稱,但您始終可以使用

打印目錄(事件)

或者

打印目錄(event.widget)

一種常見的方法是使用通用函數,但不完全相同的回調(通過lambda閉包,正如賈斯汀的回答所指出的那樣)。

有兩種不完美的替代方案依賴於工具包的內部結構:

  • _name在小部件中提供私有屬性_name
  • pytkgen 根具有widgets字典,您可以迭代以找到小部件名稱( name = [k for k, v in root.widgets.iteritems() if v == event.widget][0] )。 為了更好的代碼分離,您可以使用event.widget._nametowidget('.')從小部件中檢索根

值得注意的是,這些解決方案不適用於不為其回調提供事件的按鈕command 將動作綁定到按鈕優先通過command完成,因為它實現了按鈕的通常行為(釋放時的動作,您可以通過離開按鈕來中止......)。

暫無
暫無

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

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