You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在不同控制台或设备间传输变量?基于QTPY实现numpy数组跨设备高效传输的技术咨询

Efficiently Transfer Numpy Arrays Between QtPy App Instances (With Chat Functionality)

Great question! Using sendTextMessage() for numpy arrays is definitely inefficient—let’s dive into better approaches that play nicely with QtPy (or alternative tools) while keeping your chat feature working smoothly.

1. Use Qt WebSocket’s Binary Message Support (Best for QtPy Integration)

Qt’s QWebSocket has built-in support for binary messages via sendBinaryMessage() and the binaryMessageReceived signal—this is way faster than text-based transmission since it skips string encoding/decoding overhead.

Step 1: Serialize Numpy Arrays to Bytes

Numpy arrays can be directly converted to raw bytes with arr.tobytes(). To reconstruct the array on the receiving end, you’ll need to send metadata (dtype and shape) along with the raw data.

Sending Side Code:

import numpy as np
import json
from qtpy.QtWebSockets import QWebSocket

def send_numpy_array(ws: QWebSocket, arr: np.ndarray):
    # Pack metadata (dtype and shape) into a JSON string
    meta = {
        "dtype": str(arr.dtype),
        "shape": arr.shape
    }
    meta_bytes = json.dumps(meta).encode("utf-8")
    
    # Send metadata length first (4-byte big-endian int) so receiver knows how much to read
    meta_length = len(meta_bytes).to_bytes(4, byteorder="big")
    
    # Combine metadata length, metadata, and array bytes into one binary message
    message = meta_length + meta_bytes + arr.tobytes()
    ws.sendBinaryMessage(message)

# For chat messages, keep using sendTextMessage with a prefix to distinguish
def send_chat_message(ws: QWebSocket, text: str):
    ws.sendTextMessage(f"CHAT:{text}")

Receiving Side Code:

import numpy as np
import json
from qtpy.QtWebSockets import QWebSocket

def on_binary_message_received(message):
    # Extract metadata length (first 4 bytes)
    meta_length = int.from_bytes(message[:4], byteorder="big")
    
    # Extract and parse metadata
    meta_bytes = message[4:4+meta_length]
    meta = json.loads(meta_bytes.decode("utf-8"))
    
    # Extract array bytes and reconstruct the numpy array
    arr_bytes = message[4+meta_length:]
    arr = np.frombuffer(arr_bytes, dtype=np.dtype(meta["dtype"]))
    arr = arr.reshape(meta["shape"])
    
    # Do something with the received array
    print(f"Received numpy array with shape {arr.shape}")

def on_text_message_received(message):
    # Handle chat messages by checking the prefix
    if message.startswith("CHAT:"):
        chat_text = message[5:]
        print(f"Chat message: {chat_text}")
    # (Optional: Handle other text-based commands if needed)

# Connect signals when setting up your WebSocket:
# ws.binaryMessageReceived.connect(on_binary_message_received)
# ws.textMessageReceived.connect(on_text_message_received)

2. Use Efficient Serialization Libraries (Like MsgPack)

For even more compact metadata (faster than JSON), use msgpack instead. It’s lightweight and designed for high-performance data serialization.

Example with MsgPack:

import msgpack

def send_numpy_array_msgpack(ws: QWebSocket, arr: np.ndarray):
    data = {
        "type": "numpy_array",
        "dtype": str(arr.dtype),
        "shape": arr.shape,
        "data": arr.tobytes()
    }
    packed_data = msgpack.packb(data)
    ws.sendBinaryMessage(packed_data)

def on_binary_message_received(message):
    unpacked = msgpack.unpackb(message)
    if unpacked.get("type") == "numpy_array":
        arr = np.frombuffer(unpacked["data"], dtype=np.dtype(unpacked["dtype"]))
        arr = arr.reshape(unpacked["shape"])
        print(f"Received array (MsgPack): {arr.shape}")

3. Alternative: ZeroMQ for High-Performance Cross-Machine Transfer

If you need even better performance (especially for very large arrays or high-throughput scenarios), consider ZeroMQ. It’s a lightweight messaging library that supports multiple patterns (like PUB/SUB or REQ/REP) and integrates well with QtPy via QSocketNotifier to fit into Qt’s event loop.

Quick ZeroMQ Example:

import zmq
import numpy as np

# Sending side (PUB socket)
context = zmq.Context()
sender = context.socket(zmq.PUB)
sender.bind("tcp://*:5555")  # Listen on port 5555

def send_numpy_zmq(arr: np.ndarray):
    sender.send_array(arr)  # pyzmq has built-in send_array/recv_array

# Receiving side (SUB socket)
receiver = context.socket(zmq.SUB)
receiver.connect("tcp://your_remote_ip:5555")
receiver.setsockopt_string(zmq.SUBSCRIBE, "")

def receive_numpy_zmq():
    arr = receiver.recv_array()
    return arr

To combine chat with ZeroMQ, you can use separate sockets: one for chat (text messages) and one for numpy arrays, or add a type field to your messages to distinguish between them.

Key Notes for Production:

  • Large Arrays: For very big arrays, split them into chunks and send sequentially, then reassemble on the receiving end to avoid memory overload.
  • Security: If communicating over untrusted networks, avoid pickle (it’s insecure) and use encrypted WebSockets (wss://) or ZeroMQ with encryption.
  • Error Handling: Add checks for message integrity (e.g., checksums) and handle connection drops gracefully in your Qt app.

内容的提问来源于stack exchange,提问作者The Krehbiel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 22:32:35