1

wx.Panels を作成するために使用する threading.Thread のサブクラスがあり (それらのほとんどは 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()
4

1 に答える 1

1

実際に RandomPanel をどこに渡すかわかりません。それを作成し、関数が終了すると破棄されます。実際にパネルを渡すことはなく、親だけを渡します。個人的には、wx.CallAfter を使用して PubSub メッセージをメイン アプリケーション クラスに送信し、そこにパネルを作成するか、PubSub メッセージでパネルを渡すだけです。

Pubsub のチュートリアルは次のとおりです。

そして、これはpubsubとthreadsを持つものです:

于 2012-09-12T13:55:44.493 に答える