【发布时间】:2018-12-18 14:55:01
【问题描述】:
我正在使用 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 配置,如何解决?
【问题讨论】:
-
如果你先执行
mainloop,那么while循环直到用户关闭窗口后才会开始。如果你先执行 while 循环,那么 mainloop 将永远不会运行,窗口也永远不会出现。一般来说,Tkinter 不能很好地处理无限循环。最好定期做一点工作,然后将控制权交还给主循环。这通常使用root.after或线程来完成。 -
您似乎试图在窗口被破坏后配置按钮。为什么要在窗户被破坏后这样做?
-
在这种情况下,您需要做的是将 while 循环的主体放入事件处理程序回调中,该回调会在选择更改时运行一次,而不是永远运行一次。跨度>
标签: python python-3.x tkinter