如何将数据从线程发送到 Gtk 应用程序?

问题描述 投票:0回答:1

我有以下代码:

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()

程序基本上在一个线程上运行一个套接字服务器,在主线程上运行一个 gtk 应用程序。我想要做的是,每次套接字收到请求时,将收到的消息发送到 gtk 应用程序,gtk 应用程序使用该消息更新他的标签。我正在尝试使用

queue
来做到这一点,但我被困在
self.queue.get()
上,因为我不知道如何在不阻止 GTK 主循环的情况下观看消息。我如何在不阻塞主 gtk 循环的情况下观察队列消息,有更好的方法吗?

python multithreading sockets gtk3
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)  # this line


class MyWindow(Gtk.Window):
    ...
    def update_gui_from_queue():
        q.get()
        # do what you want with the data
        return False  # to stop repetition

© www.soinside.com 2019 - 2024. All rights reserved.