장기 실행 백그라운드 (데몬) 프로세스와 wx 기반 UI가있는 앱이 있습니다. 백그라운드 프로세스는 실행중인 데몬 프로세스에서 상태 업데이트를 얻기 위해 UI가 읽어야하는 다중 처리 .JoinableQueue()에 메시지를 넣습니다. 내가 겪고있는 문제는 AwaitStatusReportThreadClass 인스턴스가 UI에 메시지를 전달하는 동안 UI가 응답하지 않게됩니다. 아래 코드를 실행 한 다음 창 크기를 조정하려고하면 앱이 응답하지 않는 것으로 표시됩니다. 스레드가 결합 가능 대기열 메시지에 응답하여 wx Phoenix UI를 업데이트하도록하려면 어떻게합니까?
나는 Python27 32 비트, 내 애플 다양한 파이썬 파일로 구성되어wxPython에의 4.0.0a3 (피닉스)를 사용하여 Windows 7이 실행 해요,하지만 난 아래의 코드 오류를 재현 할 수 있었다. 꽤 간단합니다. here을 설명하는 pub/sub 메서드를 사용하여 UI를 업데이트하기 위해 AwaitStatusReportThreadClass라는 클래스를 만들었습니다. 이 클래스의 init 메소드에는 상태 메시지를 확인하는 무한 루프가 있습니다. 하나가 발견되면 StatusBar 메시지를 업데이트합니다.
import multiprocessing
import threading
import wx
import sys
from wx.lib.pubsub import pub
class AwaitStatusReportThreadClass(threading.Thread):
"""This class should pass messages to the UI class"""
def __init__(self, messageQueue):
"""Init worker Thread Class"""
self.messageQueue = messageQueue
threading.Thread.__init__(self)
self.start()
def run(self):
"""This code executes when the thread is run"""
KeepRunningStatusThread = True
while KeepRunningStatusThread:
sys.stdout.flush()
try:
msg = self.messageQueue.get()
self.messageQueue.task_done()
except:
pass
if msg == "Shutdown":
# Kill this thread
KeepRunningStatusThread = False
else:
pub.sendMessage("UI", msg=msg)
class UI2(wx.Frame):
"""This class is the UI"""
def __init__(self, taskQueue, messageQueue, stopQueue, parent=None):
self.taskQueue = taskQueue
self.messageQueue = messageQueue
self.stopQueue = stopQueue
wx.Frame.__init__(self, parent, title="TestApp")
#Main panel
sizerMain = wx.BoxSizer(wx.VERTICAL)
# Add the status bar
panelStatusBar = wx.Panel(self)
sizerStatusBar = wx.BoxSizer(wx.HORIZONTAL)
panelStatusBar.SetSizer(sizerStatusBar)
self.StatusBar_Main = wx.StatusBar(panelStatusBar, wx.NewId())
sizerStatusBar.Add(self.StatusBar_Main, 1, wx.EXPAND | wx.LEFT | wx.RIGHT, 2)
#Add the status bar sizer to the main sizer
sizerMain.Add(panelStatusBar, 0, wx.EXPAND)
#Add the progress bar
panelProgressBar = wx.Panel(self)
sizerProgressBar = wx.BoxSizer(wx.HORIZONTAL)
panelProgressBar.SetSizer(sizerProgressBar)
self.Gauge_ProgressBar = wx.Gauge(panelProgressBar, wx.NewId())
sizerProgressBar.Add(self.Gauge_ProgressBar, 1, wx.EXPAND)
sizerMain.Add(panelProgressBar,0,wx.EXPAND)
#Layout the frame
self.SetSizer(sizerMain)
self.SetAutoLayout(1)
sizerMain.Fit(self)
self.Layout()
self.Show(show=True)
#Subscribe to messages from the messageQueue
pub.subscribe(self.HandleStatusUpdate, "UI")
AwaitStatusReportThreadClass(self.messageQueue)
def HandleStatusUpdate(self, msg):
"""
This def updates the UI from a pubsub subscription
"""
StatusBar = self.StatusBar_Main
StatusBar.PushStatusText(msg)
if __name__ == "__main__":
#Make multiprocessing work when app is frozen
multiprocessing.freeze_support()
taskQueue = multiprocessing.JoinableQueue() #Specifies tasks to be completed by the GenInst process
messageQueue = multiprocessing.JoinableQueue() #Holds status messages/progress messages to update the message zone and progress bar in the UI
stopQueue = multiprocessing.JoinableQueue() #Allows cancel operation button to function
messageQueue.put("Please wait while the GenInst background process starts...")
#Start the UI
app = wx.App(False)
frame = UI2(taskQueue=taskQueue, messageQueue=messageQueue, stopQueue=stopQueue)
app.MainLoop()
어떤 조언이 필요합니까?