python3/gtk+ 未显示启动画面
Splash screen not showing with python3/gtk+
我的一个应用程序需要一段时间来收集它需要的所有数据并显示 window。因此,我决定创建一个简单的启动画面来通知用户发生了一些事情。不幸的是,飞溅 window 并未完全绘制:它显示为黑色矩形并在完成后消失。
我使用 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 the splash screen" 评论中的代码),但这并没有解决问题。
我在看什么?
以下代码作为编辑发布在 OP 中(已从 OP 中删除,因为它被认为是对原始问题的充分回答。
正如 theGtknerd 指出的那样:它做了它需要做的事情,这是可以接受的,因为 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"))
我的一个应用程序需要一段时间来收集它需要的所有数据并显示 window。因此,我决定创建一个简单的启动画面来通知用户发生了一些事情。不幸的是,飞溅 window 并未完全绘制:它显示为黑色矩形并在完成后消失。
我使用 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 the splash screen" 评论中的代码),但这并没有解决问题。
我在看什么?
以下代码作为编辑发布在 OP 中(已从 OP 中删除,因为它被认为是对原始问题的充分回答。
正如 theGtknerd 指出的那样:它做了它需要做的事情,这是可以接受的,因为 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"))