在 Python-gtk 的应用程序中进行一些繁重的工作时,我在显示启动屏幕时遇到了一些问题。我一直在谷歌上搜索并找到了这个链接:http://code.activestate.com/recipes/577919-splash-screen-gtk/。由于这个例子很清楚,所以我下载了该程序并在我的计算机上运行它。然而,启动画面没有显示其内容。 难道是Gtk的某些配置参数设置错误?怎么添加代码:
while gtk.events_pending():
gtk.main_iteration()
显示闪屏在我的情况下不起作用?
感谢您的帮助
我尝试添加:
while gtk.events_pending():
gtk.main_iteration()
就在
self.window.show_all()
中的 splashScreen
之后,就成功了。在此之前,它没有显示文本,“这应该不会花太长时间......:)”。
这之所以有效,是因为它确保了启动画面立即呈现,而不是让它偶然出现,我想这必须随机地对某些人(编写此代码的人和在此处回复的人)起作用,而不是对其他人(你和我)。
我知道这是一个非常老的问题,但我对 Gtk+3 也有同样的问题,并且使用 Gtk.events_pending() 没有效果,所以我采取了不同的路线。
基本上,我只是按下一个按钮来手动清除启动屏幕,我已经看到很多商业应用程序都这样做。然后,在创建主窗口后,我在启动屏幕上调用 window.present() ,以将启动屏幕保持在前面。这似乎只是 Gtk+3 需要实际显示闪屏内容before显示其后面打开的主窗口的暂停。
class splashScreen():
def __init__(self):
#I happen to be using Glade
self.gladefile = "VideoDatabase.glade"
self.builder = Gtk.Builder()
self.builder.add_from_file(self.gladefile)
self.builder.connect_signals(self)
self.window = self.builder.get_object("splashscreen")
#I give my splashscreen an "OK" button
#This is not an uncommon UI approach
self.button = self.builder.get_object("button")
#Button cannot be clicked at first
self.button.set_sensitive(False)
#Clicking the button will destroy the window
self.button.connect("clicked", self.clear)
self.window.show_all()
#Also tried putting this here to no avail
while Gtk.events_pending():
Gtk.main_iteration()
def clear(self, widget):
self.window.destroy()
class mainWindow():
def __init__(self, splash):
self.splash = splash
#Tons of slow initialization steps
#That take several seconds
#Finally, make the splashscreen OK button clickable
#You could probably call splash.window.destroy() here too
self.splash.button.set_sensitive(True)
if __name__ == "__main__":
splScr = splashScreen()
#Leaving this here, has no noticeable effect
while Gtk.events_pending():
Gtk.main_iteration()
#I pass the splashscreen as an argument to my main window
main = mainWindow(splScr)
#And make the splashscreen present to make sure it is in front
#otherwise it gets hidden
splScr.window.present()
Gtk.main()
我测试了您提供的链接中的代码,它确实显示了闪屏的组件。但它可能似乎没有为您显示它们,也许是因为启动画面窗口没有给出尺寸?我补充道:
self.window.set_size_request(300,300)
查看示例代码,果然标签确实出现了。
虽然 Chris Harrington 的答案有效,但它使用了许多已弃用的 API,并且需要手动按下按钮才能关闭对话框,因此我想提供一个不使用这两种方法的替代解决方案:
import time
import gi
import threading
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, GLib
class SplashScreen(Gtk.Dialog):
__gtype_name__ = "SplashScreen"
def __init__(self):
super().__init__(title="Loading - Example App", modal=True)
self.set_decorated(False)
self.set_default_size(512, 522) # add 10 pixels vertically for label
label = Gtk.Label(label="Loading...")
img = Gtk.Image.new_from_file("splash_screen_image_512x512.jpg")
box = self.get_content_area()
box.add(img)
box.add(label)
class MainWindow(Gtk.ApplicationWindow):
__gtype_name__ = "MainWindow"
def __init__(self):
Gtk.ApplicationWindow.__init__(self, title='Example App')
label = Gtk.Label(label="All done!")
self.add(label)
self.set_default_size(200, 100)
self.connect('destroy', Gtk.main_quit)
self.set_position(Gtk.WindowPosition.CENTER_ALWAYS)
def do_work(win, mainWin):
time.sleep(5) # 5 sec sleep to simulate blocking operation
win.destroy()
mainWin.show_all()
win = SplashScreen()
win.show_all()
mainWin = MainWindow()
# use thread to allow blocking I/O ops without preventing execution of Gtk.main() below
worker_thread = threading.Thread(target=lambda: do_work(win, mainWin))
worker_thread.start()
Gtk.main()