【问题标题】:Opening a wx.Frame in Python via a new thread通过新线程在 Python 中打开 wx.Frame
【发布时间】:2009-08-04 19:42:49
【问题描述】:

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

我通过创建一个应用程序并启动一个线程来做到这一点:

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

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

有什么想法吗?提前致谢!

【问题讨论】:

    标签: python multithreading wxpython


    【解决方案1】:

    您不需要线程。缺点是启动窗口会在加载时阻塞,但只有当您想要更新它的内容(动画)或想要能够拖动它时,这才是一个问题。例如,可以通过定期调用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()
    

    【讨论】:

    • 完美 - 在尝试线程之前,我曾想过类似的事情,但我无法将所有部分放在一起......谢谢!
    猜你喜欢
    • 1970-01-01
    • 2017-11-27
    • 2019-04-30
    • 2012-07-27
    • 2022-10-20
    • 1970-01-01
    • 1970-01-01
    • 2022-11-12
    • 2015-10-08
    相关资源
    最近更新 更多