[英]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
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.