Python tkinter GUI 冻结/崩溃

Vem*_*ddy -1 python tkinter

from Tkinter import *
import tkFileDialog
import tkMessageBox
import os
import ttk

import serial
import timeit
import time

######################################################################################
class MyApp:
    def __init__(self, parent):
########################################################
#Setup Frames

        self.MiddleFrame = Frame(parent) #Middle Frame
        self.MiddleFrame.pack()
        #GLOBAL VARIABLES
        self.chip_number = 0 #number of chip testing
###########################################
        #Middle Frame setup  
        Label(self.MiddleFrame, text='Done').grid(row=8, column=1, sticky = E)
        self.Done = Canvas(self.MiddleFrame, bg="yellow", width=10, height=10)
        self.Done.grid(row=8, column=2)         
        Label(self.MiddleFrame, text='Chip Number:').grid(row=9, column=1, sticky = E)
        #start button
        self.button1 = Button(self.MiddleFrame,state=NORMAL, command= self.start_pre)
        self.button1["text"]= "START"
        self.button1.grid(row=1, column=2, sticky = E)
########################################### 
#Action of Start Button
    def start_pre(self):

        x = 0
        while x<10000:         
            self.start_button()
            x=x+1

#Talking to Board
    def start_button(self):
        #increase chip count number and update
        self.chip_number += 1
        Label(self.MiddleFrame, text=str(self.chip_number)).grid(row=9, column=2, sticky = E)
        #reset-yellow
        self.reset_color()          
        print "Still Working", self.chip_number
        self.Done.configure(background="green")
        self.Done.update_idletasks()                 

###############################################################
#Color Boxes
#Reset
    def reset_color(self):
        self.Done.configure(background="yellow")
        self.Done.update_idletasks() 
###############################################################################################################
#Start Programs
root = Tk() #makes window
root.title("Interface")
myapp = MyApp(root) #this really runs program
root.mainloop() #keep window open                                                                           
Run Code Online (Sandbox Code Playgroud)

对于我的程序,我首先按下开始按钮。我将打印“仍在工作”,GUI 将更新芯片编号并一遍又一遍地闪烁完成指示灯。开始按钮转到将执行 10000 次的函数。然而,经过 3000 次迭代后,GUI 冻结了,但程序仍然打印“仍然工作”。如何防止 GUI 崩溃?

Bry*_*ley 5

您的代码有很多问题。其一,这是根本性的缺陷:

while self.stop == True:         
    self.start_button()
    time.sleep(0.5)
Run Code Online (Sandbox Code Playgroud)

您根本不能指望 GUI 能够正确地处理这样的代码。作为一般经验法则,您永远不应该拥有 GUI 调用的主线程sleep。导致sleep事件循环无法处理任何事件,包括低级别事件,例如刷新屏幕的请求。

sleepstackoverflow 上已经多次询问和回答了的使用。您可能会发现其中一些问题很有用。例如,

您还有另一个属于内存泄漏类别的问题。从 while 循环中,您可以self.start_button()无限期地调用。这种情况大约每秒发生一次,因为在循环中调用 sleep 半秒,在start_button.

每次调用 时start_button,您都会创建另一个标签小部件,并将其堆叠在第 9 行第 2 列中所有先前小部件的顶部。最终这将导致您的程序崩溃。我很惊讶它会导致你的程序如此快地失败,但这不是重点。

我的建议是从一个简单的示例开始,该示例除了每秒更新一个标签之外什么也不做。让它发挥作用,以便您了解基本机制。然后,一旦它开始工作,您就可以添加从串行端口读取的代码。