python - Tkinter在同时更新多个标签时没有响应

时间:2013-09-02 17:54:25

标签: python user-interface python-3.x tkinter

我正在使用内置的Python GUI Tkinter对程序进行原型设计,当我尝试同时更新多个标签时遇到了一些麻烦。 GUI可以处理一些刷新,但在10秒左右后它会冻结。我需要在非常接近的同时更新所有标签,因为每个标签都会显示不同的传感器数据。

现在,我正在使用random模块不断生成数字来代替实际数据。将有10个左右的标签同时执行此操作,我想确保tkinter可以处理它。标签也将每秒钟更新一次(大约200毫秒)。我在Windows上使用python 3.3。

我已经阅读了一些选项,但我对tkinter缺乏经验。 链接: Here. And Here.

我应该考虑多线程吗?多重?我也没有任何经验,但我愿意学习是否意味着解决这个问题。

我正在尝试使用tkinter做什么?我应该使用pygame还是其他GUI?我在这里缺少什么?

import random
from tkinter import *

class Application(Frame):
    """The GUI window"""
    def __init__(self, master):
        """Setup the Frame"""
        super(Application, self).__init__(master)
        self.grid() 
        self.setupWidgets()
        self.update()

    def setupWidgets(self):
        """Setup widgets for use in GUI"""

        #setup data readings
        self.data_lbl_txt = "Data Readings"
        self.data_lbl = Label(self, text = self.data_lbl_txt)
        self.data_lbl.grid(row = 0, column = 1, columnspan = 2, sticky = E)


        #setup first data piece
        self.data1_txt = "First piece of data:"
        self.data1_lbl = Label(self, text = self.data1_txt)
        self.data1_lbl.grid(row = 1, column = 1, sticky = W)

        self.data1 = StringVar()
        self.data1_Var = Label(self, textvariable = self.data1)
        self.data1_Var.grid(row = 1, column = 2, sticky = W)

        #setup second data piece
        self.data2_txt = "Second piece of data:"
        self.data2_lbl = Label(self, text = self.data2_txt)
        self.data2_lbl.grid(row = 2, column = 1, sticky = W)

        self.data2 = StringVar()
        self.data2_Var = Label(self, textvariable = self.data2)
        self.data2_Var.grid(row = 2, column = 2, sticky = W)


    def update(self):
        self.data1.set(random.randint(1,10))
        self.data1_Var.after(200, self.update)

        self.data2.set(random.randint(1,10))
        self.data2_Var.after(200, self.update)



root = Tk()
root.title("Data Output")
root.geometry("600x250")
window = Application(root)


window.mainloop()

1 个答案:

答案 0 :(得分:3)

我相信您在update方法中无意中创建了fork bomb

此代码:

def update(self):
    self.data1.set(random.randint(1,10))
    self.data1_Var.after(200, self.update)

    self.data2.set(random.randint(1,10))
    self.data2_Var.after(200, self.update)

意味着每次调用该方法时,它都会被再次调用两次(或者更确切地说,将来是200毫秒,因为你有.after(200, self.update)两次。

这意味着代替:

update is called 1x
200 millisecond gap
update is called 1x
200 millisecond gap
update is called 1x
200 millisecond gap
update is called 1x
200 millisecond gap
update is called 1x
200 millisecond gap...

你有这个:

update is called 1x
200 millisecond gap
update is called 2x
200 millisecond gap
update is called 4x
200 millisecond gap
update is called 8x
200 millisecond gap
update is called 16x
200 millisecond gap...

它会在大约10秒(或10,000毫秒)后冻结,因为它试图立即调用2 ^ 50(或1125899906842624)update个函数!

我认为(自从我使用Tkinter以来已经有一段时间了),解决方法是在该函数中执行root.after。或者,您可以制作多个不同的update函数,每个标签一个,每个函数只调用after一次。