【发布时间】:2016-03-22 09:45:41
【问题描述】:
我有一个 wxpython 应用程序,我启动应用程序并显示主框架。它有一个按钮。当我按下按钮时,我想要一个 pyprogress (wx.lib.agw.pyprogress) 出现,并且我想在 pyprogress 运行时向主框架添加 5 个小部件。 pyprogress 应该显示如下消息:“添加小部件 1”、“添加小部件 2”...我尝试在单独的线程中运行 pyprogress,但是当我尝试更新 pyprogress 消息并添加小部件时同时到主机,我得到这个错误:
PyAssertionError: C++ assertion "wxThread::IsMain()" failed at ..\..\src\msw\evtloop.cpp(182) in wxGUIEventLoop::Dispatch(): only the main thread can process Windows messages
如何更新pyprogress 并同时将小部件添加到大型机?
更新:
以下代码可以正常工作,但我不知道它是如何工作的。它从线程更新 GUI 窗口和 PyProgress 窗口,我没有得到任何 only the main thread can process Windows messages。请解释为什么它没有给出任何错误。
import wx
import wx.lib.agw.pyprogress as PP
import threading
ID_ADD_BUTTON = 100
ID_ADD_BUTTON2 = 101
class MyForm(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY, "My Panel", size=(400,300))
self.panel = wx.Panel(self, wx.ID_ANY)
self.mytext = wx.StaticText(self.panel, -1, "Start", size=(20,-1))
self.toolbar = wx.ToolBar(self, -1, style=wx.TB_FLAT|wx.BORDER_RAISED)
self.toolbar.AddLabelTool(ID_ADD_BUTTON, 'Refresh', wx.ArtProvider.GetBitmap(wx.ART_PLUS))
self.toolbar.Bind(wx.EVT_TOOL, self.refreshButton, id=ID_ADD_BUTTON)
self.toolbar.Realize()
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.sizer.Add(self.toolbar, 0, wx.EXPAND)
self.sizer.Add(self.panel, 1, wx.EXPAND)
self.SetSizer(self.sizer)
def refreshButton(self, event):
self.myprogress = ProgressThread()
self.toolbar2 = wx.ToolBar(self, -1, style=wx.TB_FLAT|wx.BORDER_RAISED)
self.toolbar2.AddLabelTool(ID_ADD_BUTTON2, 'Print', wx.ArtProvider.GetBitmap(wx.ART_PLUS))
self.toolbar2.Bind(wx.EVT_TOOL, self.refreshButton, id=ID_ADD_BUTTON2)
update = MyThread(self.mytext)
self.toolbar2.Realize()
self.myprogress.dlg.UpdatePulse("toolbar 2 is added")
for i in xrange(250):
self.myprogress.dlg.UpdatePulse(str(i))
#print "toolbar 2 is added"
self.sizer.Add(self.toolbar2, 0, wx.EXPAND)
self.Layout()
for i in xrange(8000, 8005):
self.myprogress.dlg.UpdatePulse(str(i))
toolbar2 = wx.ToolBar(self, -1, style=wx.TB_FLAT|wx.BORDER_RAISED)
toolbar2.AddLabelTool(ID_ADD_BUTTON2, 'Print', wx.ArtProvider.GetBitmap(wx.ART_PLUS))
toolbar2.Bind(wx.EVT_TOOL, self.refreshButton, id=ID_ADD_BUTTON2)
toolbar2.Realize()
self.toolbar2.Realize()
self.sizer.Add(toolbar2, 0, wx.EXPAND)
self.myprogress.keepGoing = False
def refreshButton2(self, event):
print "button 2 is pressed"
class ProgressThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
style = wx.PD_APP_MODAL
self.dlg = PP.PyProgress(None, -1, "Updating Data ",
"Please wait...",
agwStyle=style)
self.start()
def run(self):
self.dlg.SetGaugeProportion(20/100.0)
self.dlg.SetGaugeSteps(50)
self.dlg.SetGaugeBackground(wx.WHITE)
self.dlg.SetFirstGradientColour(wx.WHITE)
self.dlg.SetSecondGradientColour(wx.GREEN)
self.keepGoing = True
while self.keepGoing:
wx.MilliSleep(30)
try:
self.dlg.UpdatePulse()
except:
pass
self.dlg.Destroy()
class MyThread(threading.Thread):
def __init__(self, my_text):
self.my_text= my_text
threading.Thread.__init__(self)
self.start()
def run(self):
for i in xrange(300):
self.my_text.SetLabel(str(i))
# Run the program
if __name__ == "__main__":
app = wx.PySimpleApp()
frame = MyForm().Show()
app.MainLoop()
【问题讨论】:
标签: python multithreading user-interface wxpython