2012-09-12 56 views
1

返回wx.Panel我從threading.Thread一個子類,我用它來創建wx.Panels(因爲他們大多是I/O限制),並通過wx.PostEvent送他們到我的WX。幀。從threading.Thread子

的問題是,經過線程結束,已發送的面板被破壞,丟失,留下框架空白。我相信這是與執行後線程本身被銷燬的事實相關聯的。添加time.sleep(S)到所述螺紋的最後一行允許看到所述框架對於s秒內的面板,而螺紋被凍結,這證明該板實際上創建。

下面是框架的代碼,interess你:

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() 

回答

1

我看不出你居然通過RandomPanel任何地方。你創建它,然後當函數結束時,它被破壞。你從來沒有真正通過面板,但只是父母。就個人而言,我會用wx.CallAfter發送PubSub的消息,你的主應用程序類,並在那兒建立一個面板或只是通過面板在PubSub的消息。

這裏有PubSub的教程:

而且這裏有一個與發佈 - 訂閱和線程:

+0

面板作爲一個屬性傳遞的事件 << event = MyEvents.Control_NewPanel(panel = panel)>> EvtHandler可以使用event.panel獲取面板對象 至於wx.CallAfter,它構建在wx.PostEvent上,所以我猜想通過面板使用它會導致相同的錯誤,但我會稍後嘗試。 – pcarvalho

+1

我想我需要一個小的可運行的例子來看看,爲什麼不工作 –

相關問題