我的一个应用程序需要一段时间来收集所需的所有数据并显示窗口。所以,我决定创建一个简单的启动画面来通知用户发生了什么。不幸的是,启动窗口没有完全绘制:它显示一个黑色矩形,完成后消失。
我使用this示例代码(python 2.7)作为基础。
这是我的(简化代码):
#! /usr/bin/env python3
# Make sure the right Gtk version is loaded
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from time import sleep
class Splash(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self)
# Set position and decoration
self.set_position(Gtk.WindowPosition.CENTER)
self.set_decorated(False)
# Add box and label
self.box = Gtk.Box()
self.add(self.box)
self.lbl = Gtk.Label()
self.lbl.set_label("My app is loading...")
self.box.pack_start(self.lbl, True, True, 0)
# Show the splash screen without causing startup notification
# https://developer.gnome.org/gtk3/stable/GtkWindow.html#gtk-window-set-auto-startup-notification
self.set_auto_startup_notification(False)
self.show_all()
self.set_auto_startup_notification(True)
# Ensure the splash is completely drawn before moving on
while Gtk.events_pending():
Gtk.main_iteration()
if __name__ == '__main__':
# Initiate and show the splash screen
splash = Splash()
# Simulate the start of my app which takes a while
sleep(5)
# Destroy the splash window
splash.destroy()
我甚至尝试使用GObject.timeout_add来线程化show函数(包含“Show the splash screen”注释中的代码),但这并没有解决问题。
我在看什么?
答案 0 :(得分:1)
以下代码作为OP中的编辑发布(从OP中删除,因为它被认为是对原始问题的充分答案。
正如格特纳德所指出的那样:它做了它需要做的事情并且它是可以接受的,因为Gtk对象没有从主线程更新。
这是脚本的线程版本:
#! /usr/bin/env python3
# Make sure the right Gtk version is loaded
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
from threading import Thread
from time import sleep
class Splash(Thread):
def __init__(self):
super(Splash, self).__init__()
# Create a popup window
self.window = Gtk.Window(Gtk.WindowType.POPUP)
self.window.set_position(Gtk.WindowPosition.CENTER)
self.window.connect('destroy', Gtk.main_quit)
self.window.set_default_size(400, 250)
# Add box and label
box = Gtk.Box()
lbl = Gtk.Label()
lbl.set_label("My app is loading...")
box.pack_start(lbl, True, True, 0)
self.window.add(box)
def run(self):
# Show the splash screen without causing startup notification
# https://developer.gnome.org/gtk3/stable/GtkWindow.html#gtk-window-set-auto-startup-notification
self.window.set_auto_startup_notification(False)
self.window.show_all()
self.window.set_auto_startup_notification(True)
# Need to call Gtk.main to draw all widgets
Gtk.main()
def destroy(self):
self.window.destroy()
class MainUI(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self)
# Set position and decoration
self.set_position(Gtk.WindowPosition.CENTER)
self.lbl = Gtk.Label()
self.lbl.set_label("Main window started")
self.add(self.lbl)
self.connect('destroy', Gtk.main_quit)
# Initiate and show the splash screen
print(("Starting splash"))
splash = Splash()
splash.start()
print(("Simulate MainUI work"))
sleep(5)
# Destroy splash
splash.destroy()
print(("Splash destroyed"))
print(("Starting MainUI"))
self.show_all()
if __name__ == '__main__':
# Now show the actual main window
MainUI()
Gtk.main()
print(("MainUI ended"))