为什么不能修改Class的Tkinter Button配置?

时间:2018-07-10 16:59:21

标签: python python-3.x tkinter

我正在使用Tkinter在Python中构造一个简单的十六进制编辑器。我希望能够通过更改按钮的颜色来指示在GUI中选择值(“ 0000”)。 为了实现这一点,我将每个按钮实例化为一个for循环内的类,并将每个实例放入列表中以在代码中稍后引用它们。当我尝试在while循环中更改类的Button API属性时,当十六进制编辑器关闭时,IDLE将显示错误:

Traceback (most recent call last):
  File "C:/Users/Administrator/Desktop/Files/Python/hex editor.py", line 64, in <module>
    ml.button.configure(bg='#00FF00', fg='#000000')
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\tkinter\__init__.py", line 1479, in configure
    return self._configure('configure', cnf, kw)
  File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\tkinter\__init__.py", line 1470, in _configure
    self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
_tkinter.TclError: invalid command name ".!frame.!frame.!button"

按钮的预期行为是,当单击任何“ 0000”时,所选按钮将变为绿色并保持不变,直到按下另一个按钮。 (即,按下的按钮将变为绿色,而先前选择的按钮将变为黑色)

源代码:

from tkinter import *

selected_i = 0
selected_j = 0

data_w = 16
address_w = 8

class mem_location:
    def __init__(self, row, column, data):
        self.row = row
        self.column = column
        self.data = data
        self.button = Button(subframe,
                             text=self.data,
                             font=('Consolas',9),
                             bd=0,
                             command=self.select)
        self.button.pack(side=LEFT)
        self.button.configure(bg='#000000', fg='#00FF00')

    def select(self):
        selected_i = self.row
        selected_j = self.column        

root = Tk()
root.configure(bg="black")
root.title('Hex Editor')
frame = Frame(root,
              padx=30,
              pady=10,
              bg='black')
frame.pack()

ml_list = []

for i in range((1<<address_w)>>4):
    subframe = Frame(frame,
                     padx=10,
                     bg='black')
    subframe.pack()

    addr_label = Label(subframe,
                       text=hex(i<<4)+"    ",
                       bg='black',
                       fg='#00FF00',
                       width=5)
    addr_label.pack(side = LEFT)

    for j in range(16):
        ml_list.append(mem_location(i, j, '0000'))

root.mainloop()

while True:
    for ml in ml_list:
        if selected_i == ml.row and selected_j == ml.column:
            ml.button.configure(bg='#00FF00', fg='#000000')
        else:
            ml.button.configure(bg='#000000', fg='#00FF00')

我目前正在学习有关Tkinter的知识。为什么我不能修改类的Button配置以及如何解决?

1 个答案:

答案 0 :(得分:0)

root.mainloop之后的代码要等到窗口关闭后才能运行,因此您要在窗口关闭后尝试修改按钮。

相反,您可以像这样在submit方法中移动代码:

from tkinter import *

# You don’t need selected_i and selected_j anymore

data_w = 16
address_w = 8

class MemLocation:

def __init__(self, data):
    # Same code without self.row and self.column

def select(self):
    for ml in [ml_ for ml_ in ml_list if ml_ is not self]:  # All elements except this one
        ml.button.config(bg='#000', fg='#0F0')
    self.button.config(bg='#0F0', fg='#000')

# Same code here

root.mainloop()
#END

请注意,我根据PEP 8重命名了该类,但还有许多其他改进可能,例如使MemLocation从FrameButton继承,或添加事件侦听器以使代码更简洁。