2017-07-21 228 views
1

對於我正在編寫的代碼,我試圖設置它以便在Tkinter UI中,當您按下按鈕時,該按鈕將變爲禁用狀態,並且當您按下按鈕時另一個按鈕被禁用,當前禁用的按鈕將再次啓用。Tkinter按鈕已禁用/啓用點擊

import tkinter as tk 
from tkinter import ttk 

def btnPressed(index): 
    print("Button {0} disabled".format(index)) 
    for i in range(len(buttons)): 
     print("Button {0}, State: {1}".format(index, buttons[index]['state'])) 
     if buttons[i]['state'] == 'disabled': 
      buttons[i].configure(state = 'normal') 
    buttons[index].configure(state = 'disabled') 


root = tk.Tk() 
buttons = [] 
btn1 = ttk.Button(root, text = "Button 1", command = lambda: btnPressed(0)) 
btn1.pack() 
buttons.append(btn1) 
btn2 = ttk.Button(root, text = "Button 2", command = lambda: btnPressed(1)) 
btn2.pack() 
buttons.append(btn2) 
btn3 = ttk.Button(root, text = "Button 3", command = lambda: btnPressed(2)) 
btn2.pack() 
buttons.append(btn3) 
root.mainloop() 

現在我可以得到它,讓按鈕禁用自己,但是不會回到它們的「正常」狀態。我試圖做一些bug測試將

print("Button {0}, State: {1}".format(index, buttons[index]['state']))

for循環,所以我可以看到每一個按鈕的當前狀態對其進行檢查的if語句之前。

每個按鈕,雖然在用戶界面上被禁用,仍然有一個狀態值'normal'。所以顯然有些問題,但我不確定那是什麼。

回答

2

如果你檢查buttons[index]['state']的類型,你會發現它是<class '_tkinter.Tcl_Obj'>而不是string這意味着你的if語句總是失敗。您需要將其轉換爲字符串才能真正比較。

if str(buttons[i]['state']) == 'disabled': 

順便說一下,您已經使用for循環。利用它。您不需要在該循環中使用i

def btnPressed(index): 
    for btn in buttons: 
     if str(btn['state']) == 'disabled': 
      btn.configure(state = 'normal') 
    buttons[index].configure(state = 'disabled') 
+0

甜菜給我吧。我正要發佈我的答案:P。 –

+0

非常感謝。我無法弄清楚這是爲什麼我無法檢查值類型的IDLE調試器。 – Skitzafreak

4

您正在使用ttk中的Button類而不是tkinter。它的狀態屬性是一個對象,而不是一個字符串。

要測試ttk小部件是否處於特定狀態,可以使用instate方法。例如:

if buttons[i].instate[["disabled",]]: 
    ... 

您也可以使用state方法,該方法返回狀態。 ttk狀態比tk狀態更復雜,所以你找回一個列表。例如,buttons[i].state()將返回('disabled',)

另外,你是否知道你可以遍歷按鈕而不必使用索引?它會讓你的代碼更容易閱讀:

for button in buttons: 
    if button['state'] == ...