在 Python 中处理线程上的 GTK 对象
Handling GTK Objects on Threads in Python
我正在 Python 中创建一个应用程序,它使用 GTK 来构建 UI,并且我不太清楚在线程上处理 GTK 对象,例如 GtkProgressBar 对象。
上下文如下:
我尝试在主线程上进行下载,我添加了一个 GObject.timeout_add
来脉冲条,直到下载结束。但是在第一个脉冲之后 UI 冻结了。
直到出现OK,线程冻结,直到下载完成,所以任何组件都会被更新。解决方案:创建一个新线程。
我创建了这个新线程来进行下载和其他操作。在此线程上,我收到进行更新的进度条。但是当下载是 运行 并且我添加 GObject.timeout_add
来脉冲条时,UI 再次冻结。新解决方案:创建第三个线程。
所以我的线程看起来像这样:
Main-Thread
'---- Thread 1
'------Thread 2
所以,在 Thread 1
上,我做了另一件事并更新了 UI,而在 Thread 2
上,我进行了下载并添加了 GObject.timeout_add
并在那里我可以更新进度条。在 Thread 1
我加入了 Thread 2
我使用 GObject.idle_add
函数处理 Gtk 对象。
但是我很困惑为什么进度条的下载和更新在 Thread 2
上运行良好而在 Thread 1
上运行良好
有人可以向我解释为什么会这样,或者如果我错过了有关处理 GTK 对象的内容。
谢谢
如果您阻止 Gtk 主循环,window 和小部件将变得无响应。这就是为什么您不能在主线程中进行下载的原因。从下载线程更新 Gtk.ProgressBar 可能会起作用,具体取决于您的实现方式。
这是一种下载内容并使 ProgressBar 正常工作的方法:
from gi.repository import Gtk, GLib
import threading
import urllib.request
class Window(Gtk.Window):
def __init__(self):
super().__init__()
self.connect('delete-event', Gtk.main_quit)
self.progress = Gtk.ProgressBar()
self.add(self.progress)
self.show_all()
# Start download
self.thread = threading.Thread(target=self.download)
self.thread.start()
GLib.timeout_add_seconds(1, self.download_pulse)
def download(self):
urllib.request.urlretrieve('<link>')
def download_pulse(self):
if self.thread.is_alive():
self.progress.pulse()
return True
return False
win = Window()
Gtk.main()
我正在 Python 中创建一个应用程序,它使用 GTK 来构建 UI,并且我不太清楚在线程上处理 GTK 对象,例如 GtkProgressBar 对象。
上下文如下:
我尝试在主线程上进行下载,我添加了一个 GObject.timeout_add
来脉冲条,直到下载结束。但是在第一个脉冲之后 UI 冻结了。
直到出现OK,线程冻结,直到下载完成,所以任何组件都会被更新。解决方案:创建一个新线程。
我创建了这个新线程来进行下载和其他操作。在此线程上,我收到进行更新的进度条。但是当下载是 运行 并且我添加 GObject.timeout_add
来脉冲条时,UI 再次冻结。新解决方案:创建第三个线程。
所以我的线程看起来像这样:
Main-Thread
'---- Thread 1
'------Thread 2
所以,在 Thread 1
上,我做了另一件事并更新了 UI,而在 Thread 2
上,我进行了下载并添加了 GObject.timeout_add
并在那里我可以更新进度条。在 Thread 1
我加入了 Thread 2
我使用 GObject.idle_add
函数处理 Gtk 对象。
但是我很困惑为什么进度条的下载和更新在 Thread 2
上运行良好而在 Thread 1
有人可以向我解释为什么会这样,或者如果我错过了有关处理 GTK 对象的内容。
谢谢
如果您阻止 Gtk 主循环,window 和小部件将变得无响应。这就是为什么您不能在主线程中进行下载的原因。从下载线程更新 Gtk.ProgressBar 可能会起作用,具体取决于您的实现方式。
这是一种下载内容并使 ProgressBar 正常工作的方法:
from gi.repository import Gtk, GLib
import threading
import urllib.request
class Window(Gtk.Window):
def __init__(self):
super().__init__()
self.connect('delete-event', Gtk.main_quit)
self.progress = Gtk.ProgressBar()
self.add(self.progress)
self.show_all()
# Start download
self.thread = threading.Thread(target=self.download)
self.thread.start()
GLib.timeout_add_seconds(1, self.download_pulse)
def download(self):
urllib.request.urlretrieve('<link>')
def download_pulse(self):
if self.thread.is_alive():
self.progress.pulse()
return True
return False
win = Window()
Gtk.main()