【问题标题】:Good approach for updating the GUI continuously in wxPython using threads?使用线程在 wxPython 中持续更新 GUI 的好方法?
【发布时间】:2014-04-16 08:12:24
【问题描述】:

我正在 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()

感谢您的宝贵时间!

【问题讨论】:

    标签: python multithreading python-2.7 user-interface wxpython


    【解决方案1】:

    您可以定义您的私有“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()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-04-06
      • 1970-01-01
      • 1970-01-01
      • 2016-01-19
      • 2012-12-12
      • 1970-01-01
      • 2023-04-04
      • 1970-01-01
      相关资源
      最近更新 更多