Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么不能修改类的Tkinter按钮配置?_Python_Python 3.x_Tkinter - Fatal编程技术网

Python 为什么不能修改类的Tkinter按钮配置?

Python 为什么不能修改类的Tkinter按钮配置?,python,python-3.x,tkinter,Python,Python 3.x,Tkinter,我正在使用Tkinter用Python构建一个简单的十六进制编辑器。我希望能够通过更改按下按钮的颜色来指示在GUI中选择0000s的值。 为了实现这一点,我将每个按钮实例化为for循环中的一个类,并将每个实例放入一个列表中,以便稍后在代码中引用它们。当我试图改变while循环中类的按钮API属性时,当hex编辑器关闭时,IDLE会打印一个错误: Traceback (most recent call last): File "C:/Users/Administrator/Desktop/Fi

我正在使用Tkinter用Python构建一个简单的十六进制编辑器。我希望能够通过更改按下按钮的颜色来指示在GUI中选择0000s的值。 为了实现这一点,我将每个按钮实例化为for循环中的一个类,并将每个实例放入一个列表中,以便稍后在代码中引用它们。当我试图改变while循环中类的按钮API属性时,当hex编辑器关闭时,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时,所选按钮将变为绿色,并一直保持绿色,直到按下另一个按钮。i、 e按下的按钮将变为绿色,先前选择的按钮将变为黑色

源代码:

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。为什么我不能修改类的按钮配置以及如何解决这个问题?

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

请注意,我根据重命名了该类,但还有许多其他改进,如使MemLocation从Frame或Button继承,或添加事件侦听器以使代码更干净。

如果先执行mainloop,则while循环直到用户关闭窗口后才会启动。如果先执行while循环,则mainloop将永远不会运行,窗口也永远不会出现。一般来说,Tkinter不能很好地处理无限循环。最好定期做一点工作,然后将控制权交还给主循环。这通常是通过root.after或threading完成的。您似乎试图在窗口被破坏后配置按钮。在这种情况下,您需要做的是将while循环的主体放入事件处理程序回调中,该回调在选择更改时运行一次,而不是一次又一次地运行。