Python线程

时间:2010-06-07 08:10:39

标签: python multithreading tkinter

我正在尝试创建一个简单的程序,该程序不断显示和更新显示CPU使用情况的标签,同时还有其他不相关的内容。

我已经做了足够的研究,知道可能会涉及线程化。但是,我很难将我在线程的简单示例中看到的内容应用到我想要做的事情上。

我目前的目标:

import Tkinter
import psutil,time

from PIL import Image, ImageTk

class simpleapp_tk(Tkinter.Tk):
    def __init__(self,parent):
        Tkinter.Tk.__init__(self,parent)
        self.parent = parent
        self.initialize()

    def initialize(self):

        self.labelVariable = Tkinter.StringVar()
        self.label = Tkinter.Label(self,textvariable=self.labelVariable)
        self.label.pack()

        self.button = Tkinter.Button(self,text='button',command=self.A)
        self.button.pack()

    def A (self):
        G = str(round(psutil.cpu_percent(), 1)) + '%'
        print G

        self.labelVariable.set(G)

    def B (self):
        print "hello"


if __name__ == "__main__":
    app = simpleapp_tk(None)
    app.mainloop()

在上面的代码中,我基本上试图让命令A持续运行,同时允许在用户按下按钮时完成命令B.

2 个答案:

答案 0 :(得分:4)

您永远不应该尝试从不是主线程的线程更改UI元素。

您可能想要的是after(delay_ms, callback, args)。某些信息可以在http://www.pythonware.com/library/tkinter/introduction/x9507-alarm-handlers-and-other.htm处结束。

作为示例,这是一个显示时钟的快速脚本(注意:我从未真正使用过Tk)。

from Tkinter import *
from time import strftime

class App(Frame):
    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.label_var = StringVar()
        self.label = Label(self, textvariable=self.label_var)
        self.label.pack()
        # Start the loop
        self.go()

    def go(self):
        self.label_var.set(strftime("%H:%M:%S"))
        # The callback is only called once, so call it every time
        self.after(1000, self.go)

app = App()
mainloop()

答案 1 :(得分:2)

您不需要线程来完成这么简单的任务。您可以简单地安排您的任务每隔一秒左右运行一次,这可以使用'after'方法完成;

首先,将此方法添加到simpleapp_tk类:

def update(self):
    G = str(round(psutil.cpu_percent(), 1)) + '%'
    self.labelVariable.set(G)
    self.after(1000, self.update)

然后,在您的initialize方法中添加此调用:

self.update()

这将导致标签更新为当前的cpu值。然后,更新方法将重新安排自己在一秒钟内再次运行。