我有一个 python 程序,当我在线程中运行 bash 脚本并显示一些消息时,我想要一个进度条。
当我单击一个按钮时,线程开始启动脚本,但消息和进度条仅在线程完成时才会响应,仅显示最后一条消息。
阅读时,我知道我正在阻塞主循环,但我不知道如何解决这个问题。
我的程序的简化代码,问题是在调用“on_fixme_button_pressed”时:
from gi.repository import Gtk, Gdk, Pango, GObject, GLib
import os, sys
import xml.etree.ElementTree as etree
from urllib.request import urlopen
from subprocess import Popen
import threading
UI_FILE = "remendo_gtk.ui"
#UI_FILE = "/usr/local/share/remendo_gtk/ui/remendo_gtk.ui"
GObject.threads_init()
class GUI:
def __init__(self):
self.builder = Gtk.Builder()
self.builder.add_from_file(UI_FILE)
self.builder.connect_signals(self)
self.window = self.builder.get_object('remendo')
self.event_treeview = self.builder.get_object('event_treeview')
self.event_info = self.builder.get_object('event_info')
self.progressbar = self.builder.get_object('progressbar')
self.progressbar_lock = threading.Lock()
self.selected_event = ''
self.url_script = ''
self.local_script = ''
self.window.connect("destroy", lambda _: Gtk.main_quit())
self.set_event_list()
self.window.show_all()
def pulse_progressbar(self):
if threading.active_count() > 1:
self.progressbar.pulse()
return True
self.progressbar.set_fraction(0.0)
self.progressbar_lock.release()
return False
def on_fixme_button_clicked(self, button):
self.event_info.set_label("Fixing now...")
script = threading.Thread(target=self.run_script(), args=(self,))
script.start()
if self.progressbar_lock.acquire(False):
GLib.timeout_add(250, self.pulse_progressbar)
def run_script(self):
try:
self.local_script = '/tmp/%s.sh' % self.selected_event.replace(" ", "_")
script = urlopen(self.url_script)
localscript = open(self.local_script, 'wb')
localscript.write(script.read())
localscript.close()
command = ['bash', self.local_script]
p = Popen(command)
p.communicate()
#self.event_solved()
self.event_info.set_label("My work is done. Good day!")
except:
self.event_info.set_label("Script failed: %s" % self.local_script)
return False
def main():
app = GUI()
Gtk.main()
if __name__ == "__main__":
sys.exit(main())