我有一个多窗口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()
被调用?
所需的程序流程为
- 橱窗
- 运行安装
- 隐藏窗口(并显示下一个窗口)
没有任何用户交互
我使用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()
关于线程的更多信息