Программы Gui запускаются в основном цикле, и я считаю, что обновления должны происходить в основном цикле. (Кто-то может уточнить здесь или действительно, скажите мне, что я не прав).
Обычно способ достижения этого - генерировать событие из wx.lib.newevent
или использовать что-то вроде pubsub
. Однако они обычно генерируются с помощью Thread
, а не Process
, опять же, кто-то может поправить меня (я такой же нечеткий, как и следующий человек по этому вопросу).
См. Здесь: Многопроцессорная обработка Python, PyAudio и wxPython
и здесь: wxpython 3.0 и многопроцессорность - обновление графического интерфейса пользователя из фонового процесса
для справочной информации
и здесь для подробного разрешения: https://wiki.wxpython.org/MultiProcessing
Ответ, по-видимому, заключается в использовании Queue
из multiprocessing
и использовании wx.Timer
для периодической проверки этой очереди на наличие обновлений.
Я разработал быстрый скрипт для иллюстрации решения с помощью вашего кода. По крайней мере, это должна быть разумная отправная точка, с которой вы можете прогрессировать.
Помимо первоначального изменения текста статуса, он также обновляется каждые 5 секунд, просто чтобы доказать свою правоту.
import multiprocessing
import wx
class MyFrame(wx.Frame):
def __init__(self, parent, title):
wx.Frame.__init__(self, parent, title=title, size=(300,200))
self.sb = self.CreateStatusBar()
self.sb.SetStatusText('Original text')
self.Show(True)
self.timer = wx.Timer(self)
self.process_timer = wx.Timer(self)
self.Bind(wx.EVT_TIMER, self.poll, self.timer)
self.Bind(wx.EVT_TIMER, self.process, self.process_timer)
self.timer.Start(1000)
self.process_timer.Start(5000)
self.cnt = 0
# Poll for a queue entry with which to update the statusbar
def poll(self, event):
print("Polling")
if q.empty():
return
q_mess = q.get()
self.sb.SetStatusText(q_mess)
#Fire off a new process every 5 seconds to demonstrate the update
def process(self, event):
self.cnt += 1
p = multiprocessing.Process(target=doWork, args=(q,self.cnt))
p.start()
def doWork(q,cnt=0):
print ('In doWork')
q.put("New status "+str(cnt))
q = multiprocessing.Queue()
p = multiprocessing.Process(target=doWork, args=(q,0))
app = wx.App(False)
frame = MyFrame(None, 'Status Text')
p.start()
app.MainLoop()
![enter image description here](https://i.stack.imgur.com/COLer.png)