首页 > 解决方案 > Tkinter 每次都冻结导致 Python 没有响应

问题描述

我正在尝试将 tkinter 用于一个基本的弹出窗口,让您开始和停止记录数据。但是,每次我运行它时,窗口都会冻结并且我得到“Python 没有响应”。

我用谷歌搜索它,发现使用 sleep() 是一个常见原因,但由于我没有在我的代码中使用它,我不确定问题可能是什么。

import serial 
import numpy as np 
import msvcrt as m
import time
import os
from tkinter import * 

moment = time.strftime("%Y-%b-%d_%H%M%S",time.localtime())

class Application(Frame):
    def __init__(self,master):
        sd = "Data"
        try:
            os.mkdir(sd)
        except Exception:
            pass
        global f
        f= open(os.path.join(sd, "data"+ moment +".txt"),"w+")
        self.f = f
        super(Application,self).__init__(master)
        self.pack()
        self.createWidgets()
        self._alarm_id = None
        self._paused = False

    def createWidgets(self):
        self.someFrame = Frame(self)
        self.startButton = Button(self.someFrame, text="Start     Recording",command=self.startRecord)
        self.startButton.pack(side=LEFT)

        self.stopButton = Button(self.someFrame, text="Stop Recording", command=self.stopRecord)
        self.stopButton.pack(side=LEFT)

        self.resetButton = Button(self.someFrame, text="Reset", command=self.resetRecord)
        self.resetButton.pack(side=LEFT)
        self.someFrame.pack(side=TOP)

        self.labelvariable = StringVar()
        self.labelvariable.set("Waiting")

        self.thelabel = Label(self,textvariable = self.labelvariable,font=('Helvetica',50))
        self.thelabel.pack(side=TOP)

    def startRecord(self):
        """ Start/Resume """
        self._paused = False
        app.labelvariable.set("Recording")
        if self._alarm_id is None:
            self.record()

    def stopRecord(self):
        """ Stop/Pause """
        app.labelvariable.set("Paused")
        if self._alarm_id is not None:
            self._paused = True

    def resetRecord(self):
        """ Resets and creates new file"""
        app.labelvariable.set("Cleared")
        f = self.f
        f.close()
        sd = "Data"
        try:
            os.mkdir(sd)
        except Exception:
            pass
        moment = time.strftime("%Y-%b-%d_%H%M%S",time.localtime())
        f= open(os.path.join(sd, "data"+ moment +".txt"),"w+")
        if self._alarm_id is not None:
            self.master.after_cancel(self._alarm_id)
            self._alarm_id = None
            self._paused = False
            self.record()
            self._paused = True

    def record(self, start=True):
        if start:
            arduinoData = serial.Serial('com3', 9600)
            while self._paused is False:
                while (arduinoData.inWaiting()==0): 
                    pass
                arduinoString = arduinoData.readline() 
                vlt = float(arduinoString)   
                f.write("%d\r\n" %(vlt))
        if self._paused:
            self._alarm_id = self.master.after(1000, self.record, False)
        else:
            app.labelvariable.set("")
            self._alarm_id = self.master.after(1000, self.record, False)


if __name__ == '__main__':
    root = Tk()
    root.title("EMG")
    app = Application(root)
    root.mainloop()

标签: pythontkinter

解决方案


不要使用while声明!

使用这个: root.after():如何使用 root.after()


推荐阅读