2017-07-21 198 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'] == ...