wxPython - 导入时显示徽标
wxPython - Showing logo while importing
我是 运行 一个 wxPython 应用程序,它在开始时执行大量模块和包导入并收集有关计算机的信息(网络接口,互联网连接..)所以这需要时间,而且我' m 在那段时间显示一个标志,直到它结束。问题是如果您按下徽标会崩溃(因为导入是在 MainThread 上并且 GUI 无法响应事件),如何在导入时显示徽标而不让 GUI 崩溃? (无论如何我都不想让用户点击Logo)
在最近的一个项目中(在 Windows7 和 wxPython 2.9.5.1 上):为了在导入模块时显示 wx.SplashScreen
我们做了以下操作:
我们有一个主模块,它在开始时执行 import wx
,创建 wx.App
并显示启动画面。只有在显示初始屏幕后,我们才开始导入 "heavy" 模块。第一次启动需要 40 秒。事实上,如果用户点击闪屏,应用程序就会崩溃。更好的说法是,Windows 显示一个消息框 (EDIT2),其中包含 "Python.exe has stopped working." 如果用户单击 "Terminate",该应用实际上会 terminate/crash .如果用户什么都不做,应用程序将正常启动。所以在 Windows 上没有 "real" 崩溃。第二次启动时也不会发生(因为缓存了东西)?在随后的启动中,启动时间为 5 秒。抱歉,没有真正的答案,但评论也太长了。
编辑:添加了最小工作示例:在显示时每隔一两秒单击启动画面以使 Windows 显示 "Python has stopped working" 对话框.当 long_running()
返回时,对话框将简单地消失。
# -*- coding: utf-8 -*-
def long_running():
import time
time.sleep(10)
# does not show "Python ... stopped working ..."
#for _ in range(20):
# time.sleep(0.5)
# wx.Yield()
if __name__ == '__main__':
import wx
app = wx.App()
bitmap = wx.EmptyBitmap(300, 150, 127)
splash = wx.SplashScreen(bitmap, wx.SPLASH_TIMEOUT, 20000, None)
# Begin loading the application.
long_running()
# Application loaded.
#Destroy the splash screen.
splash.Hide()
splash.Destroy()
app.MainLoop()
受到 Tim Roberts 的启发,wxPython-users thread 我首先尝试在一个单独的线程中关闭闪屏,但没有成功(wxwidgets 抱怨它不在主线程中)。所以我做了一件我一开始就应该做的显而易见的事情:在启动时将 long 运行 设为一个单独的线程。
副作用:由于启动画面现在可以对事件做出反应,因此在单击时会消失。
import wx
class long_running(object):
def __init__(self):
bitmap = wx.EmptyBitmap(300, 150, 127)
self.mainframe = wx.Frame(None, -1, 'mainframe')
self.splash = wx.SplashScreen(bitmap, wx.SPLASH_TIMEOUT, 20000, self.mainframe)
def start(self):
import time
# mimicking something taking very long time on startup
for i in range(20):
time.sleep(0.5)
print i
wx.CallAfter(self.continue_)
def continue_(self):
#Destroy the splash screen.
if self.splash:
self.splash.Hide()
# self.splash.Destroy()
self.mainframe.Show()
if __name__ == '__main__':
import thread
app = wx.App()
long_rnn = long_running()
# Begin loading the application.
thread.start_new_thread(long_rnn.start, ())
# Application loaded.
app.MainLoop()
我是 运行 一个 wxPython 应用程序,它在开始时执行大量模块和包导入并收集有关计算机的信息(网络接口,互联网连接..)所以这需要时间,而且我' m 在那段时间显示一个标志,直到它结束。问题是如果您按下徽标会崩溃(因为导入是在 MainThread 上并且 GUI 无法响应事件),如何在导入时显示徽标而不让 GUI 崩溃? (无论如何我都不想让用户点击Logo)
在最近的一个项目中(在 Windows7 和 wxPython 2.9.5.1 上):为了在导入模块时显示 wx.SplashScreen
我们做了以下操作:
我们有一个主模块,它在开始时执行 import wx
,创建 wx.App
并显示启动画面。只有在显示初始屏幕后,我们才开始导入 "heavy" 模块。第一次启动需要 40 秒。事实上,如果用户点击闪屏,应用程序就会崩溃。更好的说法是,Windows 显示一个消息框 (EDIT2),其中包含 "Python.exe has stopped working." 如果用户单击 "Terminate",该应用实际上会 terminate/crash .如果用户什么都不做,应用程序将正常启动。所以在 Windows 上没有 "real" 崩溃。第二次启动时也不会发生(因为缓存了东西)?在随后的启动中,启动时间为 5 秒。抱歉,没有真正的答案,但评论也太长了。
编辑:添加了最小工作示例:在显示时每隔一两秒单击启动画面以使 Windows 显示 "Python has stopped working" 对话框.当 long_running()
返回时,对话框将简单地消失。
# -*- coding: utf-8 -*-
def long_running():
import time
time.sleep(10)
# does not show "Python ... stopped working ..."
#for _ in range(20):
# time.sleep(0.5)
# wx.Yield()
if __name__ == '__main__':
import wx
app = wx.App()
bitmap = wx.EmptyBitmap(300, 150, 127)
splash = wx.SplashScreen(bitmap, wx.SPLASH_TIMEOUT, 20000, None)
# Begin loading the application.
long_running()
# Application loaded.
#Destroy the splash screen.
splash.Hide()
splash.Destroy()
app.MainLoop()
受到 Tim Roberts 的启发,wxPython-users thread 我首先尝试在一个单独的线程中关闭闪屏,但没有成功(wxwidgets 抱怨它不在主线程中)。所以我做了一件我一开始就应该做的显而易见的事情:在启动时将 long 运行 设为一个单独的线程。
副作用:由于启动画面现在可以对事件做出反应,因此在单击时会消失。
import wx
class long_running(object):
def __init__(self):
bitmap = wx.EmptyBitmap(300, 150, 127)
self.mainframe = wx.Frame(None, -1, 'mainframe')
self.splash = wx.SplashScreen(bitmap, wx.SPLASH_TIMEOUT, 20000, self.mainframe)
def start(self):
import time
# mimicking something taking very long time on startup
for i in range(20):
time.sleep(0.5)
print i
wx.CallAfter(self.continue_)
def continue_(self):
#Destroy the splash screen.
if self.splash:
self.splash.Hide()
# self.splash.Destroy()
self.mainframe.Show()
if __name__ == '__main__':
import thread
app = wx.App()
long_rnn = long_running()
# Begin loading the application.
thread.start_new_thread(long_rnn.start, ())
# Application loaded.
app.MainLoop()