[英]Tkinter Freeze on grid_remove
因此,我试图构建一个GUI,在其中输入一些信息,清除输入字段,然后添加新的输入字段。 但是,当我尝试通过grid_remove从根清除帧时,应用程序冻结。 相关代码如下。
import tkinter
from threading import Thread
class PinGui(tkinter.Frame):
def __init__(self, client):
self.client = client
self.root = client.root
self.add_pin = client.add_pin
self.end = client.end
tkinter.Frame.__init__(self, self.root)
self.grid_widgets()
self.grid_buttons()
self.bind_keys()
self.grid(padx=32, pady=32)
def grid_buttons(self, b1='Add', b2='Reset', b3='Quit'):
self.addButton = tkinter.Button(self, text=b1, command=self.validate)
self.resetButton = tkinter.Button(self, text=b2, command=self.reset)
self.quitButton = tkinter.Button(self, text=b3, command=self.end)
self.buttons = [self.addButton, self.resetButton, self.quitButton]
for i in range(3): self.buttons[i].grid(row=i, column=11)
def grid_widgets(self):
widths = [3,3,4,4,6]
self.pin_vars = []
self.pin_fields = []
for i in range(5):
self.pin_vars.append(tkinter.StringVar())
self.pin_fields.append(
tkinter.Entry(self,width=widths[i], textvariable=self.pin_vars[i])
)
self.pin_fields[i].grid(row=0, column=2*i, padx=3)
self.pin_fields[0].focus_set()
def bind_keys(self):
self.root.bind_all("<Return>", self.validate)
self.root.bind_all("<Escape>", self.end)
def validate(self, args=None):
self.client.pin = []
for field in self.pin_fields:
self.client.pin.append(field.get())
Thread(target=self.add_pin).start()
def ungrid(self):
for field in self.pin_fields: field.grid_remove()
for button in self.buttons: button.grid_remove()
self.display.grid_remove()
和:
class PinClient:
def __init__(self):
self.root = tkinter.Tk()
self.gui = PinGui(self)
self.pins = []
def add_pin(self):
self.gui.reset()
if 'display' in self.__dict__:
self.pins.append(self.pin)
self.display.add_pin(self.pin)
self.ping("Enter PIN for Comp %s:" % len(self.display.col1))
if len(self.display.col1) > 5:
self.end() # THIS IS WHERE IT FREEZES
else:
self.subject = self.pin
self.display = Display(self.root, self.pin)
self.display.grid(row=1, padx=32, pady=32)
self.ping("Enter PIN for Comp 1:")
def ping(self, msg):
self.gui.d_var.set(msg)
def end(self, args=None):
self.gui.ungrid()
class Display(tkinter.Frame):
def __init__(self, master, pin):
tkinter.Frame.__init__(self, master)
self.pin = pin
self.col1 = []
self.col2 = []
self.col1.append(tkinter.Label(self, text="Subject:"))
self.col2.append(tkinter.Label(self, text=self.pin))
self.grid_widgets()
def grid_widgets(self):
self.ungrid()
for i in range(len(self.col1)):
self.col1[i].grid(row=i, column=0)
self.col2[i].grid(row=i, column=1)
def ungrid(self):
for i in range(len(self.col1)):
self.col1[i].grid_remove()
self.col2[i].grid_remove()
def add_pin(self, pin):
self.col1.append(tkinter.Label(self, text="Comp %s:" % len(self.col1)))
self.col2.append(tkinter.Label(self, text=pin))
i = len(self.col1)
self.col1[i-1].grid(row=i, column=0)
self.col2[i-1].grid(row=i, column=1)
这似乎与线程有关,但是我还没有找到应该冻结的任何原因。 任何帮助是极大的赞赏!
Tkinter不是线程安全的。 如果您在除主线程之外的其他线程中执行任何操作都没有接触到GUI对象,那么您将获得无法预测的结果。 几乎可以肯定,是线程导致了您的问题,因为您正试图从工作线程访问小部件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.