在wxPython中使用线程持续更新GUI的好方法



我正在windows 7操作系统上使用python v2.7和wxPython v3.0的GUI应用程序。我必须不断更新我的GUI,其中包含许多面板。每个面板包含一个wx.StaticText。我必须不断更新这些wx.StaticTexts。我想用threads。此外,我正在使用pubsub模块与GUI通信以更新这些wx.StaticTexts。每件事都按预期进行。我已经创建了一个简短的演示下面我的实际问题。

问题:在下面的代码中,创建了两个线程。这两个线程都可以使用wx.CallAfter()更新GUI。如果我有100个面板需要更新呢?我需要为每个线程创建100个类更新一个特定的面板吗?我希望线程独立于其他线程工作。还有什么比这个更好的方法呢?

代码:请找到下面的示例代码来玩:

import wx
from wx.lib.pubsub import setupkwargs
from wx.lib.pubsub import pub
import time
from threading import Thread
import threading
class GUI(wx.Frame):
    def __init__(self, parent, id, title):
        screenWidth = 500
        screenHeight = 400
        screenSize = (screenWidth,screenHeight)
        wx.Frame.__init__(self, None, id, title, size=screenSize)
        self.locationFont = locationFont = wx.Font(12, wx.MODERN, wx.NORMAL, wx.BOLD)
        mainSizer = wx.BoxSizer(wx.VERTICAL)
        myPanelA = wx.Panel(self, style=wx.SIMPLE_BORDER)
        myPanelA.SetBackgroundColour('#C0FAE0')
        self.myTextA = wx.StaticText(myPanelA, -1, "I have a problem :( ")
        myPanelB = wx.Panel(self, style=wx.SIMPLE_BORDER)
        myPanelB.SetBackgroundColour('#C0FAFF')
        self.myTextB = wx.StaticText(myPanelB, -1, "Me too :( ")
        mainSizer.Add(myPanelA, 1, wx.EXPAND, 5)
        mainSizer.Add(myPanelB, 1, wx.EXPAND, 5)
        self.SetSizer(mainSizer)
        pub.subscribe(self.updatePanelA, 'Update-panelA')
        pub.subscribe(self.updatePanelB, 'Update-panelB')
    def updatePanelA(self, message):
        self.myTextA.SetLabel(message)
    def updatePanelB(self, message):
        self.myTextB.SetLabel(message)
class threadA(Thread):
    def __init__(self):
        Thread.__init__(self)
        self.start()
    def run(self):
        ObjA = updateGUI()
        ObjA.methodA()
class threadB(Thread):
    def __init__(self):
        Thread.__init__(self)
        self.start()
    def run(self):
        ObjB = updateGUI()
        ObjB.methodB()
class updateGUI():
    def methodA(self):
        while True:
            time.sleep(3)
            wx.CallAfter(pub.sendMessage, 'Update-panelA', message='Problem solved')
    def methodB(self):
        while True:
            time.sleep(5)
            wx.CallAfter(pub.sendMessage, 'Update-panelB', message='Mine too')
if __name__=='__main__':
    app = wx.App()
    frame = GUI(parent=None, id=-1, title="Problem Demo")
    frame.Show()
    threadA()
    threadB()
    app.MainLoop()
感谢您的宝贵时间!

你可以定义你的私有"selfUpdatePanel"来启动它自己的线程来更新它自己的文本字段。通过这种方式,代码将易于维护。

检查根据您的代码修改的以下代码:

import wx
from wx.lib.pubsub import setupkwargs
from wx.lib.pubsub import pub
import time
from threading import Thread
import threading

class selfUpdatePanel(wx.Panel):
    def __init__(self, parent, mystyle, interval, topic, message):
        wx.Panel.__init__(self, parent, style = mystyle)
        pub.subscribe(self.updatePanel, topic)
        self.updateMsg = message
        self.textCtrl = None
        self.interval = interval
        self.topic = topic
        pub.subscribe(self.updatePanel, self.topic)
    def setTextCtrl(self,text):
        self.textCtrl = text
    def updatePanel(self):
        self.textCtrl.SetLabel(self.updateMsg)
    def threadMethod(self):
        while True:
            print "threadMethod"
            time.sleep(self.interval)
            wx.CallAfter(pub.sendMessage, self.topic)
    def startThread(self):
        self.thread = Thread(target=self.threadMethod)
        self.thread.start()

class GUI(wx.Frame):
    def __init__(self, parent, id, title):
        screenWidth = 500
        screenHeight = 400
        screenSize = (screenWidth,screenHeight)
        wx.Frame.__init__(self, None, id, title, size=screenSize)
        self.locationFont = locationFont = wx.Font(12, wx.MODERN, wx.NORMAL, wx.BOLD)
        mainSizer = wx.BoxSizer(wx.VERTICAL)
        #myPanelA = wx.Panel(self, style=wx.SIMPLE_BORDER)
        myPanelA = selfUpdatePanel(self, wx.SIMPLE_BORDER, 3, 'Update-panelA', 'Problem solved')
        myPanelA.SetBackgroundColour('#C0FAE0')
        self.myTextA = wx.StaticText(myPanelA, -1, "I have a problem :( ")
        myPanelA.setTextCtrl(self.myTextA)
        #myPanelB = wx.Panel(self, style=wx.SIMPLE_BORDER)
        myPanelB = selfUpdatePanel(self, wx.SIMPLE_BORDER, 5, 'Update-panelB', 'Mine too')
        myPanelB.SetBackgroundColour('#C0FAFF')
        self.myTextB = wx.StaticText(myPanelB, -1, "Me too :( ")
        myPanelB.setTextCtrl(self.myTextB)
        mainSizer.Add(myPanelA, 1, wx.EXPAND, 5)
        mainSizer.Add(myPanelB, 1, wx.EXPAND, 5)
        self.SetSizer(mainSizer)
        myPanelB.startThread()
        myPanelA.startThread()

if __name__=='__main__':
    app = wx.App()
    frame = GUI(parent=None, id=-1, title="Problem Demo")
    frame.Show()
    app.MainLoop()

相关内容

  • 没有找到相关文章

最新更新