我怎样从线程发送数据到Gtk应用程序?

huangapple go评论53阅读模式
英文:

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

huangapple
  • 本文由 发表于 2023年4月16日 23:18:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/76028597.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定