显示Gtk窗口后运行操作



我有一个多窗口Gtk应用程序,它是一个安装程序。在安装过程中(这需要一些时间),我希望显示一个带有标签的窗口,通知用户安装正在进行中。所以我尝试将各自的方法绑定到show事件。

但是,这会导致窗口的出现延迟,直到方法完成,然后立即显示下一个窗口。结果是,显示前一个窗口,然后屏幕在实际安装期间变为空白,然后显示最后一个窗口。

我把这个问题归结为这样一个事实:在实际显示窗口之前,show事件显然被触发了。

这里是一个最小的剪辑来澄清我的问题。该窗口显示在呼叫sleep()之后,而不是之前。

#! /usr/bin/env python3
from time import sleep
from gi import require_version
require_version('Gtk', '3.0')
from gi.repository import Gtk

class GUI(Gtk.ApplicationWindow):
def __init__(self):
"""Initializes the GUI."""
super().__init__(title='Gtk Window')
self.set_position(Gtk.WindowPosition.CENTER)
self.grid = Gtk.Grid()
self.add(self.grid)
self.label = Gtk.Label()
self.label.set_text('Doing stuff')
self.grid.attach(self.label, 0, 0, 1, 1)
self.connect('show', self.on_show)
def on_show(self, *args):
print('Doing stuff.')
sleep(3)
print('Done stuff.')

def main() -> None:
"""Starts the GUI."""
win = GUI()
win.connect('destroy', Gtk.main_quit)
win.show_all()
Gtk.main()

if __name__ == '__main__':
main()

我怎样才能实现,窗口显示之前方法on_show()被调用?

所需的程序流程为

  1. 橱窗
  2. 运行安装
  3. 隐藏窗口(并显示下一个窗口)

没有任何用户交互

我使用multiprocessing修复了这个问题:

from ast import Gt
from time import sleep
from multiprocessing import Process
from gi import require_version
require_version('Gtk', '3.0')
from gi.repository import Gtk

class GUI(Gtk.ApplicationWindow):
def __init__(self):
"""Initializes the GUI."""
super().__init__(title='Gtk Window')
self.set_position(Gtk.WindowPosition.CENTER)
self.grid = Gtk.Grid()
self.add(self.grid)
self.label = Gtk.Label()
self.label.set_text('Doing stuff')
self.grid.attach(self.label, 0, 0, 1, 1)
def on_show():
print('Doing stuff.')
sleep(3)
print('Done stuff.')


def main() -> None:
"""Starts the GUI."""
win = GUI()
win.connect('destroy', Gtk.main_quit)
win.show_all() 
p1 = Process(target = on_show)
p1.start()
Gtk.main()

if __name__ == '__main__':
main()

基本上,发生的事情是Gtk.main()渲染你的应用程序,而show_all()只是打包小部件,所以在它延迟渲染之前放一个sleep函数。

另一种方法是使用线程(这也为实现进度条提供了一种简单的方法):

from ast import Gt
from time import sleep
import threading
from gi import require_version
require_version('Gtk', '3.0')
from gi.repository import Gtk

class GUI(Gtk.ApplicationWindow):
def __init__(self):
"""Initializes the GUI."""
super().__init__(title='Gtk Window')
self.set_position(Gtk.WindowPosition.CENTER)
self.grid = Gtk.Grid()
self.add(self.grid)
self.label = Gtk.Label()
self.label.set_text('Doing stuff')
self.grid.attach(self.label, 0, 0, 1, 1)
thread = threading.Thread(target=self.on_show)
thread.daemon = True
thread.start()
def on_show(self, *args):
print('Doing stuff.')
sleep(3)
print('Done stuff.')


def main() -> None:
"""Starts the GUI."""
win = GUI()
win.connect('destroy', Gtk.main_quit)
win.show_all() 
Gtk.main()

if __name__ == '__main__':
main()

关于线程的更多信息

最新更新