英文:
How can I send data from thread to Gtk app?
问题
以下是您提供的代码的翻译部分:
我有以下的代码:
import socket
from queue import Queue
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GLib
import threading
HOST = '' # 在所有可用的网络接口上监听
PORT = 5000 # 任意端口号
def socket_server(queue):
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((HOST, PORT))
server_socket.listen(1)
print('等待传入连接...')
while True:
client_socket, client_address = server_socket.accept()
data = client_socket.recv(1024)
print(f'从客户端接收数据: {data.decode()}')
queue.put(data.decode())
client_socket.close()
class MyWindow(Gtk.Window):
def __init__(self, queue):
self.queue = queue
Gtk.Window.__init__(self, title="GTK 应用")
self.set_default_size(400, 300)
self.label = Gtk.Label(label="欢迎使用 GTK 应用!")
self.add(self.label)
def set_label_text(self):
text = self.queue.get()
self.label.set_text(text)
if __name__ == '__main__':
q = Queue()
socket_thread = threading.Thread(target=socket_server, args=(q,))
socket_thread.start()
win = MyWindow(q)
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()
请注意,我已经翻译了您提供的代码,并按照您的要求只返回了翻译部分,没有回答您的问题。如果您有任何进一步的问题或需要帮助,欢迎提出。
英文:
I have the following code:
import socket
from queue import Queue
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk, GLib
import threading
HOST = '' # Listen on all available network interfaces
PORT = 5000 # Arbitrary port number
def socket_server(queue):
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((HOST, PORT))
server_socket.listen(1)
print('Listening for incoming connections...')
while True:
client_socket, client_address = server_socket.accept()
data = client_socket.recv(1024)
print(f'Received data from client: {data.decode()}')
queue.put(data.decode())
client_socket.close()
class MyWindow(Gtk.Window):
def __init__(self, queue):
self.queue = queue
Gtk.Window.__init__(self, title="GTK App")
self.set_default_size(400, 300)
self.label = Gtk.Label(label="Welcome to the GTK App!")
self.add(self.label)
def set_label_text(self):
text = self.queue.get()
self.label.set_text(text)
if __name__ == '__main__':
q = Queue()
socket_thread = threading.Thread(target=socket_server, args=(q,))
socket_thread.start()
win = MyWindow(q)
win.connect("destroy", Gtk.main_quit)
win.show_all()
Gtk.main()
The programs basically runs a socket server on a thread and a gtk app on the main thread. What I'm trying to do is to, every time the socket receives a request, to send the message recived to the gtk app and the gtk app update his label with that message. I'm trying to do it with queue
but I'm stuck on self.queue.get()
because I can't figure how to watch for messages without block GTK Main loop. How can I watch for queue messages without blocking the main gtk loop, are there better approaches to this?
答案1
得分: 0
在将项目添加到队列后,从子线程中调用 GLib.idle_add
,以便在主线程中执行函数。
这在 PyGObject 线程文档 中有提到。
def socket_server(queue):
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((HOST, PORT))
server_socket.listen(1)
print('Listening for incoming connections...')
while True:
client_socket, client_address = server_socket.accept()
data = client_socket.recv(1024)
print(f'Received data from client: {data.decode()}')
queue.put(data.decode())
client_socket.close()
GLib.idle_add(win.update_gui_from_queue) # 这一行
class MyWindow(Gtk.Window):
...
def update_gui_from_queue(self):
q.get()
# 对数据进行处理
return False # 停止重复执行
英文:
after you add an item in the queue, call GLib.idle_add
from the child thread to have a function execute in the main thread.
this is mentioned in the PyGObject threads documentation
def socket_server(queue):
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((HOST, PORT))
server_socket.listen(1)
print('Listening for incoming connections...')
while True:
client_socket, client_address = server_socket.accept()
data = client_socket.recv(1024)
print(f'Received data from client: {data.decode()}')
queue.put(data.decode())
client_socket.close()
GLib.idle_add(win.update_gui_from_queue) # this line
class MyWindow(Gtk.Window):
...
def update_gui_from_queue(self):
q.get()
# do what you want with the data
return False # to stop repetition
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论