wxPython自定义启动画面和进度条

2 投票
1 回答
1338 浏览
提问于 2025-04-18 09:57

我该如何在wxPython中创建一个自定义的启动画面,里面有一个加载条,并且在启动时自动开始显示?

我的回答和代码示例在下面。

1 个回答

1

我一直在尝试用wxPython创建一个自定义的启动画面,这个画面里有一个进度条(加载条),希望它能在启动时自动加载。经过一些调整,我终于做出来了。为了实现这个功能,我需要重写应用程序的MainLoop()方法。下面是我使用的应用模块。

class Application(wx.App):
"""Inherits from wx.App and serves as the entry point for the wxPython application. 
To run the program, an instance of this class is created and its method "MainLoop" is called.
"""

    def __init__(self):
        """Initializes our wx.App by calling its super method. It also instantiates a new 
        ApplicationManager which manages the different components of the project session.
        """
        wx.App.__init__(self, redirect = False)  


    def OnInit(self):
        """Instantiates the main frame. The OnInit method is only available for classes that derive 
        wx.App. Override this method to do application initialization.
        """
        self.appManager = ApplicationManager()
        self.appManager.applicationFrame = ApplicationFrame(self)
        self.appManager.splashScreen = SplashScreenDialog()
        self.keepRunning = True
        return True


    def MainLoop(self):
        """This function is overridden to allow the splash screen to load properly at the start 
        of the application. On the first loop, the method displays the splash screen and loads 
        the necessary files. When the application is closed, the keepRunning variable is set 
        to false (see ApplicationFrame) and the while loop is ended.
        """
        self.loadedSplashScreen = False

        # Create an event loop and make it active. If you are only going to temporarily have a nested 
        # event loop then you should get a reference to the old one and set it as the active event 
        # loop when you are done with this one...
        eventLoop = wx.GUIEventLoop()
        oldEventLoop = wx.EventLoop.GetActive()
        wx.EventLoop.SetActive(eventLoop)

        # This outer loop determines when to exit the application, for this example we let the main 
        # frame reset this flag when it closes.
        while self.keepRunning:
            # At this point in the outer loop you could do whatever you implemented your own MainLoop 
            # for. It should be quick and non-blocking, otherwise your GUI will freeze.  

            # Place splash screen events on the stack
            if (not self.loadedSplashScreen):
                self.appManager.splashScreen.Show(True)

            # This inner loop will process any GUI events until there are no more waiting.
            while eventLoop.Pending():
                eventLoop.Dispatch()

            if (not self.loadedSplashScreen):
                for i in range(0,10000000):
                    # Do loading stuff here
                    j = float(i/100000.0)
                    self.appManager.splashScreen.gauge.SetValue(j)

                self.appManager.splashScreen.Close()
                self.appManager.applicationFrame.Show(True)
                self.SetTopWindow(self.appManager.applicationFrame)
                self.loadedSplashScreen = True

            # Send idle events to idle handlers. This may need to be throttle back so 
            # there is not too much CPU time spent in the idle handlers.
            time.sleep(0.10) # Throttling back
            eventLoop.ProcessIdle()

        wx.EventLoop.SetActive(oldEventLoop)

当你关闭应用程序时,需要把self.keepRunning设置为false,这样MainLoop()方法才能结束。希望这对你有帮助!

撰写回答