Python tkinter GUI 冻结/崩溃 [英] Python tkinter GUI freezing/crashing

查看:68
本文介绍了Python tkinter GUI 冻结/崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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                                                                           

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

With my program, i first push the start button. I will print "still working" and the GUi will update chip number and blink done light over and over. The start button go to function that will execute 10000 times. However after 3000 iterations, the gui freeze, but the program is still print "still working". How do I keep the gui from crashing?

推荐答案

您的代码有很多问题.一方面,这从根本上是有缺陷的:

There are many problems with your code. For one, this is fundamentally flawed:

while self.stop == True:         
    self.start_button()
    time.sleep(0.5)

您不能指望 GUI 在使用这样的代码时能正常运行.作为一般经验法则,您永远不应该拥有 GUI 调用 sleep 的主线程.导致 sleep 会阻止事件循环处理任何事件,包括低级事件,例如刷新屏幕的请求.

You simply can't expect a GUI to behave properly with code like that. As a general rule of thumb you should never have the main thread of a GUI call sleep. Causing sleep prevents the event loop from processing any events, including low level events such as requests to refresh the screen.

sleep 的使用已经在 stackoverflow 上被多次询问和回答.您可能会发现其中一些问题很有用.例如,

The use of sleep has been asked and answered many times on stackoverflow. You might find some of those questions useful. For example,

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

You have another problem that falls into the category of a memory leak. From that while loop, you call self.start_button() indefinitely. This happens about once a second, due to sleep being called for half a second in the loop, and another half a second in start_button.

每次您调用 start_button 时,您都会创建另一个标签小部件,该小部件堆叠在第 9 行第 2 列的所有先前小部件的顶部.最终这将导致您的程序坠毁.我很惊讶它会导致您的程序如此迅速地失败,但这无关紧要.

Each time you call start_button, you create another label widget that you stack on top of all previous widgets in row 9, column 2. Eventually this will cause your program to crash. I'm surprised that it causes your program to fail so quickly, but that's beside the point.

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

My recommendation is to start over with a simple example that does nothing but update a label every second. Get that working so that you understand the basic mechanism. Then, once it's working, you can add in your code that reads from the serial port.

这篇关于Python tkinter GUI 冻结/崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆