【问题标题】:Splash screen not showing with python3/gtk+python3/gtk+ 不显示启动画面
【发布时间】:2017-10-20 20:09:39
【问题描述】:

我的一个应用程序需要一段时间来收集它需要的所有数据并显示窗口。因此,我决定创建一个简单的闪屏来通知用户发生了一些事情。不幸的是,启动窗口没有完全绘制:它显示一个黑色矩形,完成后消失。

我使用 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 来线程显示函数(包含“显示初始屏幕”注释中的代码),但这并没有解决问题。

我在看什么?

【问题讨论】:

  • 你初始化Gtk并启动主循环了吗?
  • 我做到了(据我所知)。我添加的最后一个答案是接受的答案。也许你可以看看它。

标签: python-3.x gtk splash-screen


【解决方案1】:

以下代码作为编辑发布在 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"))

【讨论】:

  • 如果您在 Splash 类中使用 Gtk.Overlay 或其他复杂对象(如 Gtk.Spinner),就会发生有趣的事情。有时 MainUI 不显示,我必须手动终止该进程。微调器有时会抛出此错误:Gdk-CRITICAL **: _gdk_frame_clock_freeze: assertion 'GDK_IS_FRAME_CLOCK (clock)' failed。再次“有时”,并不总是......
  • 我通过将窗口设为弹出窗口解决了上述问题。答案中的代码已被修改。
  • 对于正在为其应用程序寻找现成可用脚本的任何人,这就是我最终得到的结果:github.com/SolydXK/solydxk-system/blob/origin/master/usr/lib/…
  • 我在一个程序中使用它,它需要几秒钟来建立与另一台服务器的连接。为了结束启动,我调用了 GLib.idle_add(splash.destroy),所以程序不会因为线程冲突而崩溃。
猜你喜欢
  • 2018-12-07
  • 2014-01-22
  • 2023-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-12
  • 2014-05-05
相关资源
最近更新 更多