linux - Unable to initialize a window and wait for a process to end in Python 3 + GTK+ 3 -
i'm new object-oriented programming, python , gtk+3, though have decent knowledge of procedural programming (mainly c).
i'm trying build simple python + gtk+ 3 script run pkexec apt-get update under linux.
i have mainwindow class (based on gtk.window class) contains button object named button (based on gtk.button class) triggers new_update_window() method defined in mainwindow upon clicked event;
the new_update_window() method initializes updatewindow object updatewindow class (based on gtk.window class) contains label object named label (based on gtk.label class) , calls methods show_all() , update() defined in updatewindow;
the update() method supposed change label, run pkexec apt-get update , change label again.
the problem no matter 1 of following occurs:
- if run
subprocess.popen(["/usr/bin/pkexec", "/usr/bin/apt-get", "update"])directly,update.windowshownlabelset value should set afterpkexec apt-get updatehas finished executing; - if run
subprocess.call(["/usr/bin/pkexec", "/usr/bin/apt-get", "update"])directly,update.windownot shown untilpkexec apt-get updatehas finished executing; - i tried
importingthreading, defining separaterun_update()method inupdatewindow, start function in separate thread usingthread = threading.thread(target=self.run_update),thread.start(),thread.join(), still depending on method call inrun_update()(subprocess.call()orsubprocess.popen) relative behavior described above exhibits.
tl;dr
i'm @ loss understand how accomplish i'm after, is:
- showing
updatewindow(gtk.window) - updating
label(gtk.label) inupdatewindow - running
pkexec apt-get update - updating
labelinupdatewindow
subprocess.popen():update.windowshownlabelset value should set afterpkexec apt-get updatehas finished executing;subprocess.call():update.windownot shown untilpkexec apt-get updatehas finished executing;- wrapping either of 2 in function , run function in separate thread doesn't change anything.
here's code;
not using thread (case 1, in case using subprocess.popen()):
#!/usr/bin/python3 gi.repository import gtk import subprocess class mainwindow(gtk.window): def __init__(self): gtk.window.__init__(self, title = "updater") button = gtk.button() button.set_label("update") button.connect("clicked", self.new_update_window) self.add(button) def new_update_window(self, button): update = updatewindow() update.show_all() update.update() class updatewindow(gtk.window): def __init__(self): gtk.window.__init__(self, title = "updating...") self.label = gtk.label() self.label.set_text("idling...") self.add(self.label) def update(self): self.label.set_text("updating... please wait.") subprocess.call(["/usr/bin/pkexec", "/usr/bin/apt-get", "update"]) self.label.set_text("updated.") def run_update(self): main = mainwindow() main.connect("delete-event", gtk.main_quit) main.show_all() gtk.main() using thread (case 3, in case using subprocess.popen()):
#!/usr/bin/python3 gi.repository import gtk import threading import subprocess class mainwindow(gtk.window): def __init__(self): gtk.window.__init__(self, title = "updater") button = gtk.button() button.set_label("update") button.connect("clicked", self.new_update_window) self.add(button) def new_update_window(self, button): update = updatewindow() update.show_all() update.update() class updatewindow(gtk.window): def __init__(self): gtk.window.__init__(self, title = "updating...") self.label = gtk.label() self.label.set_text("idling...") self.add(self.label) def update(self): self.label.set_text("updating... please wait.") thread = threading.thread(target=self.run_update) thread.start() thread.join() self.label.set_text("updated.") def run_update(self): subprocess.popen(["/usr/bin/pkexec", "/usr/bin/apt-get", "update"]) main = mainwindow() main.connect("delete-event", gtk.main_quit) main.show_all() gtk.main()
instead of using python's subprocess module, use gio.subprocess integrates gtk's main loop:
#!/usr/bin/python3 gi.repository import gtk, gio # ... class updatewindow(gtk.window): def __init__(self): gtk.window.__init__(self, title="updating...") self.label = gtk.label() self.label.set_text("idling...") self.add(self.label) def update(self): self.label.set_text("updating... please wait.") subprocess = gio.subprocess.new(["/usr/bin/pkexec", "/usr/bin/apt-get", "update"], 0) subprocess.wait_check_async(none, self._on_update_finished) def _on_update_finished(self, subprocess, result): subprocess.wait_check_finish(result) self.label.set_text("updated.")
Comments
Post a Comment