在一个单独的线程中,我检查pySerial Buffer(无限循环)中的信息。如果有新信息,我想在Gtk.TextView
中显示该输入。在谷歌搜索主题后,结果发现做Gtk -Stuff内线程是一个杀手。随机错误会出现,等等,这也是我遇到的问题。
我决定使用队列来同步线程和GUI。将信息放入队列非常简单,但是如果队列中有任何条目,我如何检查主循环?
某种事件会很好,如果有任何新信息可以触发。
有什么类似的吗?也许存在一个函数来实现自定义python代码到GTK3 + mainloop?
答案 0 :(得分:3)
要成功定期从线程中的事件更新GUI,我们不能简单地使用threading
来启动第二个进程。就像你提到的那样,它会导致冲突。
这里是GObject
的位置,因为它放在this (slightly outdated) link中:
在应用程序初始化时调用gobject.threads_init()。然后正常启动线程,但要确保线程不会直接执行任何GUI任务。相反,您使用gobject.idle_add来安排在主线程中执行的GUI任务
当我们将gobject.threads_init()
替换为GObject.threads_init()
而gobject.idle_add
替换为GObject.idle_add()
时,我们几乎拥有如何在Gtk应用程序中运行线程的更新版本。一个简化的示例,显示文本字段中越来越多的猴子。请参阅代码中的注释:
#!/usr/bin/env python3
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GObject
import time
from threading import Thread
class InterFace(Gtk.Window):
def __init__(self):
Gtk.Window.__init__(self, title="Test 123")
maingrid = Gtk.Grid()
maingrid.set_border_width(10)
self.add(maingrid)
scrolledwindow = Gtk.ScrolledWindow()
scrolledwindow.set_hexpand(True)
scrolledwindow.set_vexpand(True)
scrolledwindow.set_min_content_height(50)
scrolledwindow.set_min_content_width(150)
maingrid.attach(scrolledwindow, 0,0,1,1)
self.textfield = Gtk.TextView()
self.textbuffer = self.textfield.get_buffer()
self.textbuffer.set_text("Let's count monkeys")
self.textfield.set_wrap_mode(Gtk.WrapMode.WORD)
scrolledwindow.add(self.textfield)
# 1. define the tread, updating your text
self.update = Thread(target=self.counting_monkeys)
# 2. Deamonize the thread to make it stop with the GUI
self.update.setDaemon(True)
# 3. Start the thread
self.update.start()
def counting_monkeys(self):
# replace this with your thread to update the text
n = 1
while True:
time.sleep(2)
newtext = str(n)+" monkey" if n == 1 else str(n)+" monkeys"
GObject.idle_add(
self.textbuffer.set_text, newtext,
priority=GObject.PRIORITY_DEFAULT
)
n += 1
def run_gui():
window = InterFace()
# 4. this is where we call GObject.threads_init()
GObject.threads_init()
window.show_all()
Gtk.main()
run_gui()
答案 1 :(得分:1)
找到解决方案:
GObject.timeout_add
http://www.pygtk.org/pygtk2reference/gobject-functions.html#function-gobject--timeout-add
此GObject函数每X毫秒实现一次对自己的函数的回调。在这里找到一个简单的解释:
https://gist.github.com/jampola/473e963cff3d4ae96707
所以我可以每隔X毫秒减少从队列收集的所有信息。处理线程的好方法!