gpt4 book ai didi

python - pygtk 和 multiprocessing - 从另一个运行无限循环的进程不断更新 textview

转载 作者:太空狗 更新时间:2023-10-30 01:02:47 25 4
gpt4 key购买 nike

我正在使用 pygtk 构建一个 python 应用程序。它由一些激活/停用一些无限循环进程的按钮和一个应该继续显示每个进程内部发生的事情的 TextView 组成。喜欢冗长的东西。

这些过程没有结束。它们仅在用户点击相应按钮(或关闭应用程序)时停止。

出了什么问题:我无法通过这些进程在 TextView 中打印内容。也许是因为他们没有尽头...

实际上,该应用程序太大,无法在此处显示完整代码。所以我做了一个简单的小例子来说明我在做什么。

import pygtk
pygtk.require("2.0")
import gtk
import time
import glib
from multiprocessing import Process
gtk.threads_init()

class Test(gtk.Window):
def delete_event(self, widget, event, data=None):
if isinstance(self.my_process, Process):
if self.my_process.is_alive():
self.my_process.terminate()
gtk.main_quit()
return False

def __init__(self):

gtk.Window.__init__(self)
self.set_default_size(500, 400)
self.set_title(u"Test")
self.connect("delete_event", self.delete_event)

self.mainBox = gtk.VBox(False, 5)

self.text = gtk.TextView()
self.text.set_wrap_mode(gtk.WRAP_WORD)
self.button = gtk.Button("Start")

self.add(self.mainBox)
self.mainBox.pack_start(self.text, True, True, 0)
self.mainBox.pack_start(self.button, False, True, 0)

self.button.connect("clicked", self.start_clicked)

self.show_all()

def start_clicked(self, widget):
self.register_data("Starting...")
self.my_process = Process(target=self.do_something)
self.my_process.start()

def do_something(self):
while True:
time.sleep(0.5)
#get a list of a lot of things
#Do stuff with each item in the list
#show me on the gui whats going on
glib.idle_add(self.register_data, "Yo! Here I'm")
print "Hello, boy."

def register_data(self, data):
data = data + "\r\n"
#gtk.gdk.threads_enter()
buff = self.text.get_buffer()
biter = buff.get_start_iter()
buff.insert(biter, data)
#gtk.gdk.threads_leave()


if __name__ == "__main__":
mnc = Test()
mnc.set_position(gtk.WIN_POS_CENTER)
gtk.threads_enter()
gtk.main()
gtk.threads_leave()

最佳答案

删除所有.threads_init().threads_enter().threads_leave()多处理 不是线程

将要显示的数据放入子进程的 multiprocessing.Queue() 中:

def do_something(self):
while True:
#get a list of a lot of things
#Do stuff with each item in the list
#show me on the gui whats going on
self.data_queue.put("Yo! Here I'm")

并在 GUI 循环中轮询它:

def __init__(self, ...):
# ...
self.data_queue = Queue()
gobject.timeout_add(100, self.update_text)

哪里:

def update_text(self):
# receive updates from the child process here
try:
data = self.data_queue.get_nowait()
except Empty:
pass # nothing at this time
else:
self.register_data(data)
return True

为避免轮询,您可以在子进程中写入 multiprocessing.Pipe 并使用 gobject.io_add_watch() 设置 GUI 回调。这是一个完整的代码示例:

#!/usr/bin/python3
from multiprocessing import Pipe, Process
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import GObject, Gtk

# create GUI to show multiprocessing output
win = Gtk.Window()
win.set_default_size(640, 480)
label = Gtk.Label('process output')
win.add(label)

# start dummy infinite loop in a child process
def loop(conn):
import itertools, sys, time
for i in itertools.count():
conn.send(i)
time.sleep(0.1 - time.monotonic() % 0.1)

parent_conn, child_conn = Pipe(duplex=False)
Process(target=loop, args=[child_conn], daemon=True).start()
child_conn.close()

# read values from the child
def read_data(source, condition):
assert parent_conn.poll()
try:
i = parent_conn.recv()
except EOFError:
return False # stop reading
# update text
label.set_text('Result from the child: %03d' % (i,))
return True # continue reading
# . configure the callback
GObject.io_add_watch(parent_conn.fileno(), GObject.IO_IN, read_data)

win.connect('delete-event', Gtk.main_quit)
win.show_all()
Gtk.main()

您也可以do it with an arbitrary subprocess (not just a python child process) .

关于python - pygtk 和 multiprocessing - 从另一个运行无限循环的进程不断更新 textview,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13518452/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com