簡體   English   中英

Tkinter在grid_remove上凍結

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM