我有一个来自threading.Thread的子类,我用来创建wx.Panels(因为它们中的大多数是I / O绑定的)并通过wx.PostEvent发送到我的wx.Frame。
问题是线程结束后,发送的面板被破坏并丢失,使框架留空。我相信这与线程本身在执行后被销毁的事实有关。将time.sleep(s)添加到线程的最后一行允许在帧内看到面板s秒,同时线程被冻结,证明该面板实际上已创建。
以下是可能会强调您的框架的代码:
self.Bind(MyEvents.EVT_CONTROL_NEWPANEL,self.ChangePanel)
def ChangePanel(self,event):
if self.panel != None:
self.panel.Hide()
self.panel = event.panel
self.panel.Show()
和threading.thread子类的一个:
class ThreadExecute(threading.Thread):
def __init__(self,func,args):
threading.Thread.__init__(self)
self.func = func
self.args = args
self.start()
def run(self):
apply(self.func,self.args)
CreateRandomPanel(parent):
panel = RandomPanel(parent)
event = MyEvents.Control_NewPanel(panel = panel)
wx.PostEvent(parent,event)
线程结束后有没有办法让对象保持活动状态? 在螺纹上腌制物体并在框架上去除它是一个很好的选择吗?
编辑:
代码的一个小的可运行示例:
import wx
import threading
from wx.lib.newevent import NewEvent
from time import sleep
NewPanelEvent, EVT_NEWPANEL = NewEvent()
class MyFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__(self,None,size=wx.Size(350,350))
self.panel = None
self.Bind(EVT_NEWPANEL,self.ChangePanel)
self.control = MyControl(self)
self.control.NewPanel()
def ChangePanel(self,event):
if self.panel != None:
self.panel.Hide()
self.panel = event.panel
#self.Refresh()
class MyPanel(wx.Panel):
def __init__(self,parent,size):
wx.Panel.__init__(self,parent,size=size)
self.btn = wx.Button(self,label='hit me!',pos=wx.Point(25,25),size=wx.Size(75,25))
self.SetBackgroundColour(wx.Colour(255,255,0))
class MyControl(object):
def __init__(self,window):
self.window = window
def NewPanel(self):
MyThread(RandomFunction,(self.window,))
class MyThread(threading.Thread):
def __init__(self,func,args):
threading.Thread.__init__(self)
self.func = func
self.args = args
self.start()
def run(self):
apply(self.func,self.args)
def RandomFunction(window):
sleep(3)
# size = window.GetSizeTuple()
size = (250,250)
panel = MyPanel(window,size=size)
event = NewPanelEvent(panel = panel)
wx.PostEvent(window,event)
# use the sleep to prevent the thread from ending, so you can see the panel
sleep(5)
class App(wx.App):
def OnInit(self):
self.frame = MyFrame()
self.frame.Show()
self.SetTopWindow(self.frame)
return True
def main():
app = App(False)
app.MainLoop()
if __name__ == '__main__':
main()
答案 0 :(得分:1)
我看不到你在任何地方实际传递RandomPanel的位置。你创建它然后当函数结束时,它会被破坏。你从来没有真正通过面板,只是父母。就个人而言,我会使用wx.CallAfter将PubSub消息发送到您的主应用程序类,并让它在那里创建一个面板,或者只是在PubSub消息中传递面板。
这是关于Pubsub的教程:
这是pubsub和线程的一个: