Linux 无法初始化窗口并等待进程在Python 3+中结束;GTK&x2B;3.
我是面向对象编程、Python和GTK+3的新手,不过我对过程编程(主要是C)有相当的了解 我正在尝试构建一个简单的Python+GTK+3脚本,以便在Linux下运行Linux 无法初始化窗口并等待进程在Python 3+中结束;GTK&x2B;3.,linux,python-3.x,subprocess,gtk3,Linux,Python 3.x,Subprocess,Gtk3,我是面向对象编程、Python和GTK+3的新手,不过我对过程编程(主要是C)有相当的了解 我正在尝试构建一个简单的Python+GTK+3脚本,以便在Linux下运行pkexec apt get update 我有一个mainWindow类(基于Gtk.Window类),其中包含一个名为button(基于Gtk.button类)的按钮对象,该对象在单击的事件中触发新的更新窗口()方法 new\u update\u window()方法从updateWindow类(基于Gtk.window类)初
pkexec apt get update
我有一个mainWindow
类(基于Gtk.Window
类),其中包含一个名为button
(基于Gtk.button
类)的按钮对象,该对象在单击的事件中触发新的更新窗口()
方法
new\u update\u window()
方法从updateWindow
类(基于Gtk.window
类)初始化updateWindow
对象,该类包含名为label
(基于Gtk.label
类)的标签对象,并调用方法show\u all()
和update()
在updateWindow
中定义
update()
方法应该更改label
,运行pkexec apt get update
并再次更改label
问题是无论我做什么,都会出现以下情况之一:
- 如果我直接运行
subprocess.Popen([“/usr/bin/pkexec”、“/usr/bin/apt get”、“update”])
,则会显示update.Window
,但label
会立即设置为值,只有在pkexec apt get update
完成执行后才应设置该值李>
- 如果我直接运行
子进程调用([“/usr/bin/pkexec”、“/usr/bin/apt get”、“update”])
,update.Window
直到pkexec apt get update
完成执行后才会显示李>
- 我尝试了
import
ingthreading
,在updateWindow
中定义了一个单独的run\u update()
方法,并使用thread=threading.thread(target=self.run\u update)
,thread.start()
,thread.join(),在单独的线程中启动函数,但是仍然取决于我在run\u update()
(subprocess.call()
或subprocess.Popen
)中调用的方法,上面描述的相对行为会显示出来
Tl;博士
我无法理解如何实现我所追求的目标,即:
显示updateWindow
(Gtk.Window
)
在updateWindow
正在运行pkexec apt get update
在updateWindow
subprocess.Popen()
:update.Window
显示,但label
立即设置为只有在pkexec apt get update
完成执行后才应设置的值李>
subprocess.call()
:update.Window
直到pkexec apt get update
完成执行后才会显示李>
- 在函数中包装这两个函数并在单独的线程中运行函数不会改变任何事情
这是代码
不使用线程(情况1,在本例中使用subprocess.Popen()
):
#/usr/bin/python3
从gi.repository导入Gtk
导入子流程
类主窗口(Gtk.Window):
定义初始化(自):
Gtk.Window.\uuuu init\uuuu(self,title=“Updater”)
button=Gtk.button()
按钮。设置标签(“更新”)
按钮。连接(“单击”,自我更新窗口)
添加(按钮)
def新建_更新_窗口(自身,按钮):
update=updateWindow()
update.show_all()
update.update()
类更新窗口(Gtk.Window):
定义初始化(自):
Gtk.Window.uu init_uuu(self,title=“更新…”)
self.label=Gtk.label()
self.label.set_文本(“空转…”)
self.add(self.label)
def更新(自我):
self.label.set_文本(“正在更新…请稍候”)
子进程调用([“/usr/bin/pkexec”、“/usr/bin/apt get”、“update”])
self.label.set_文本(“已更新”)
def运行_更新(自我):
main=mainWindow()
main.connect(“删除事件”,Gtk.main\u退出)
main.show_all()
Gtk.main()
使用线程(案例3,在本例中使用subprocess.Popen()
):
#/usr/bin/python3
从gi.repository导入Gtk
导入线程
导入子流程
类主窗口(Gtk.Window):
定义初始化(自):
Gtk.Window.\uuuu init\uuuu(self,title=“Updater”)
button=Gtk.button()
按钮。设置标签(“更新”)
按钮。连接(“单击”,自我更新窗口)
添加(按钮)
def新建_更新_窗口(自身,按钮):
update=updateWindow()
update.show_all()
update.update()
类更新窗口(Gtk.Window):
定义初始化(自):
Gtk.Window.uu init_uuu(self,title=“更新…”)
self.label=Gtk.label()
self.label.set_文本(“空转…”)
self.add(self.label)
def更新(自我):
self.label.set_文本(“正在更新…请稍候”)
thread=threading.thread(目标=self.run\u更新)
thread.start()
thread.join()
self.label.set_文本(“已更新”)
def运行_更新(自我):
subprocess.Popen([“/usr/bin/pkexec”,“/usr/bin/apt get”,“update”])
main=mainWindow()
main.connect(“删除事件”,Gtk.main\u退出)
main.show_all()
Gtk.main()
中的
您没有等待进程终止,请重试
def run_update(self):
proc = subprocess.Popen(["/usr/bin/pkexec", "/usr/bin/apt-get", "update"])
proc.wait()
相反。这应该正确地等待完成,但不会有多大帮助,因为updateWindow.update
将从main窗口调用。new\u update\u窗口
和GUI线程将等待进程完成
当subprocess.Popen
或subprocess.call启动的进程完成时,可以使用自定义信号进行通信:
#!/usr/bin/python3
from gi.repository import Gtk, GObject
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(self)
update.show_all()
update.start_update()
class updateWindow(Gtk.Window):
def __init__(self, parent):
Gtk.Window.__init__(self, title = "Updating...")
self.label = Gtk.Label()
self.label.set_text("Idling...")
self.add(self.label)
self.parent = parent
GObject.signal_new('update_complete', self, GObject.SIGNAL_RUN_LAST,
None, (int,))
self.connect('update_complete', self.on_update_complete)
def on_update_complete(self, widget, rc):
self.label.set_text("Updated {:d}".format(rc))
# emit a signal to mainwindow if needed, self.parent.emit(...)
def start_update(self):
self.label.set_text("Updating... Please wait.")
thread = threading.Thread(target=self.run_update)
thread.start()
def run_update(self):
rc = subprocess.call(["/usr/bin/pkexec", "apt-get", "update"],
shell=False)
self.emit('update_complete', rc)
main = mainWindow()
main.connect("delete-event", Gtk.main_quit)
main.show_all()
Gtk.main()
你就快到了…
解决方案非常简单:)
你遇到的问题是
#!/usr/bin/python3
from gi.repository import Gtk, GObject
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(self)
update.show_all()
update.start_update()
class updateWindow(Gtk.Window):
def __init__(self, parent):
Gtk.Window.__init__(self, title = "Updating...")
self.label = Gtk.Label()
self.label.set_text("Idling...")
self.add(self.label)
self.parent = parent
GObject.signal_new('update_complete', self, GObject.SIGNAL_RUN_LAST,
None, (int,))
self.connect('update_complete', self.on_update_complete)
def on_update_complete(self, widget, rc):
self.label.set_text("Updated {:d}".format(rc))
# emit a signal to mainwindow if needed, self.parent.emit(...)
def start_update(self):
self.label.set_text("Updating... Please wait.")
thread = threading.Thread(target=self.run_update)
thread.start()
def run_update(self):
rc = subprocess.call(["/usr/bin/pkexec", "apt-get", "update"],
shell=False)
self.emit('update_complete', rc)
main = mainWindow()
main.connect("delete-event", Gtk.main_quit)
main.show_all()
Gtk.main()
subprocess.call(["/usr/bin/pkexec", "/usr/bin/apt-get", "update"])
self.label.set_text("Updated.")
GObject.threads_init()
GObject.idle_add()
#!/usr/bin/python3
from 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.")