代码之家  ›  专栏  ›  技术社区  ›  Fry

通过新线程在python中打开wx.frame

  •  0
  • Fry  · 技术社区  · 16 年前

    我有一个作为启动屏幕存在的框架,供用户在主程序启动之前进行选择。在用户做出选择后,我需要屏幕作为一种启动屏幕一直显示,直到主程序完成加载。

    我通过创建应用程序并启动线程来完成此操作:

    class App(wx.App):
        '''
        Creates the main frame and displays it
        Returns true if successful
        '''
        def OnInit(self):
            try:
                '''
                Initialization
                '''
                self.newFile = False
                self.fileName = ""
    
                self.splashThread = Splash.SplashThread(logging, self)
                self.splashThread.start()
                #...More to the class
    

    启动帧:

    class SplashThread(threading.Thread):
        def __init__(self, logger, app):
            threading.Thread.__init__(self)
            self.logger = logger
            self.app = app
    
        def run(self):
            frame = Frame(self.logger, self.app)
            frame.Show()
    

    应用程序值是必需的,因为它包含回调,允许主程序在用户做出选择时继续运行。问题是,启动屏幕只闪烁一毫秒,然后消失,不允许用户进行选择并阻止启动的其余部分。

    有什么想法吗?事先谢谢!

    1 回复  |  直到 16 年前
        1
  •  0
  •   Matt Razza    16 年前

    你不需要线程。缺点是启动窗口在加载时会阻塞,但只有当您想更新它的内容(对其进行动画处理)或希望能够拖动它时,这才是一个问题。可以通过定期调用解决的问题 wx.SafeYield 例如。

    import time
    import wx
    
    
    class Loader(wx.Frame):
        def __init__(self):
            wx.Frame.__init__(self, None)
            sizer = wx.BoxSizer(wx.VERTICAL)
            self.SetSizer(sizer)
            self.btn1 = wx.Button(self, label="Option 1")
            self.btn2 = wx.Button(self, label="Option 2")
            sizer.Add(self.btn1, flag=wx.EXPAND)
            sizer.Add(self.btn2, flag=wx.EXPAND)
            self.btn1.Bind(wx.EVT_BUTTON, self.OnOption1)
            self.btn2.Bind(
                wx.EVT_BUTTON, lambda e: wx.MessageBox("There is no option 2")
            )
    
        def OnOption1(self, event):
            self.btn1.Hide()
            self.btn2.Hide()
            self.Sizer.Add(
                wx.StaticText(self, label="Loading Option 1..."),
                1, wx.ALL | wx.EXPAND, 15
            )
            self.Layout()
            self.Update()
            AppFrame(self).Show()
    
    class AppFrame(wx.Frame):
        def __init__(self, parent):
            wx.Frame.__init__(self, parent)
            time.sleep(3)
            parent.Hide()
    
            # the top window (Loader) is hidden so the app needs to be told to exit
            # when this window is closed
            self.Bind(wx.EVT_CLOSE, lambda e: wx.GetApp().ExitMainLoop())
    
    
    app = wx.PySimpleApp()
    app.TopWindow = Loader()
    app.TopWindow.Show()
    app.MainLoop()