WxPython Notes (1) --- Splash Screen

WxPython Notes (1) --- Splash Screen

一、介绍
此系列文章为本人学习 wx2.8-examples 的笔记。从浅入深,逐步构造出一个略具规模的程序。所有代码可以从 [wxpy-study] 下载,使用 svn 还可以提取特定的版本。

二、代码提取

本节使用版本 2 的代码(版本1是空的),提取命令为

svn -r 2 co http://wxpy-study.googlecode.com/svn/trunk/

全部代码如下:

[Copy to clipboard] [ - ]
CODE:
#!/usr/bin/env python
#coding=utf8

import wx

class MySplashScreen (wx.SplashScreen):
    def __init__(self):
        bmp = wx.Image("bitmaps/splash.png").ConvertToBitmap()
        
        wx.SplashScreen.__init__(self, bmp,
                                 wx.SPLASH_CENTRE_ON_SCREEN|wx.SPLASH_TIMEOUT,
                                 2500, None, -1)
        self.Bind(wx.EVT_CLOSE, self.OnClose)
        # 过 2000 才显示主窗口
        self.fc=wx.FutureCall(2000, self.ShowMain)

    def OnClose(self, evt):
        # evt.Skip() 的含义有待研究
        evt.Skip()
        self.Hide()

        # 如果还没到 2000(比如用户用鼠标点了 splash 图,引发 splash 图关闭),
        # 则显示主窗口
        if self.fc.IsRunning():
            self.fc.Stop()
            self.ShowMain()

    def ShowMain(self):
        # 构造主窗口,并显示
        frame=wx.Frame(None)
        frame.Show()


class MyApp(wx.App):
    def OnInit(self):
        print "App init"
        self.SetAppName("InfoMath Demo")
        splash=MySplashScreen()
        return True

    def OnExit(self):
        print "Existing"
        
# 定义主函数
def main():
    app=MyApp(False)
    app.MainLoop()

# 调用主函数
main()

三、本节主题为如何实现一个 splash screen

程序的框架为 main 函数 -> MyApp -> MySpalshScreen -> wx.Frame. -> MainLoop().

MySplashScreen 类负责显示 splash 图。

MySplashScreen 的初始化函数中:

[Copy to clipboard] [ - ]
CODE:
bmp = wx.Image("bitmaps/splash.png").ConvertToBitmap()

读入一个 png 图,并转换成 bitmap 格式(splash 图必须为此格式)。

wx.SplashScreen.__init__(self, bmp,
                                 wx.SPLASH_CENTRE_ON_SCREEN|wx.SPLASH_TIMEOUT,
                                 2500, None, -1)

这里直接调用 wx.SplashScreen 的 __init__ 函数,感觉有点怪异。此句含义为居中,停留 2500 个时间单位。

self.fc=wx.FutureCall(2000, self.ShowMain)

FutureCall 含义为过 2000 个时间单位后调用 ShowMain,在 ShowMain 中会创建一个 wx.Frame. 并显示。之后进入主循环。
MySpalshScreen 的销毁函数

[Copy to clipboard] [ - ]
CODE:
OnClose(self, evt)

这个函数理解得不好,一开始的  evt.Skip() 和 self.Hide() 的作用未能理解。

此函数最后有几句:

[Copy to clipboard] [ - ]
CODE:
if self.fc.IsRunning():
            self.fc.Stop()
            self.ShowMain()

其作用是判断 FutureCall/ShowMain 发生了没有。因为用户点一下鼠标,Splash 图会关闭,从而进入 OnClose。如果此时 FutureCall 2000 的定时器还未到,主窗口不会弹出,程序就好像消失了一样。所以如果 splash 图销毁,应马上显示主窗口。

很好。