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

如何在Python中实现类似Qt QIODevice::readAll()的标准输入读取?

Qt与Python管道通信:实时读取所有已到达输入的解决方案

1. 文本场景:逐行读取(最简单实现)

如果Qt发送的数据是带换行符结尾的文本格式,直接循环读取每行即可,无需等待EOF:

import sys

for line in sys.stdin:
    # 移除换行符并处理数据
    raw_data = line.strip()
    # 替换为你的业务逻辑
    print(f"Received text: {raw_data}", flush=True)

Qt端配合操作:发送数据时追加换行符,示例代码:

process.write("your_content\n".toUtf8());
process.flush();

2. 二进制场景:平台适配的实时读取

如果传输的是二进制数据,需要根据操作系统选择对应方式,实现类似Qt readAll()的效果:

Unix/Linux/macOS 版本(用select监听可读事件)

import sys
import select

while True:
    # 监听stdin,设置0.1秒超时(平衡响应速度与CPU占用)
    readable, _, _ = select.select([sys.stdin.buffer], [], [], 0.1)
    if readable:
        # 读取当前缓冲区所有可用数据,1024为单次读取上限,可按需调整
        data = sys.stdin.buffer.read(1024)
        if not data:
            break  # 管道关闭时退出循环
        # 处理二进制数据
        print(f"Received {len(data)} bytes", flush=True)

Windows 版本(用msvcrt检查输入状态)

import sys
import msvcrt

while True:
    # 检查是否有输入数据可用
    if msvcrt.kbhit():
        # Windows下read()会直接读取当前缓冲区所有数据,不会等待EOF
        data = sys.stdin.buffer.read()
        if not data:
            break
        print(f"Received {len(data)} bytes", flush=True)

3. 跨平台通用方案:非阻塞模式读取

通过将stdin设置为非阻塞模式,循环尝试读取,避免平台依赖:

import sys
import time

try:
    # Unix/Linux/macOS 配置非阻塞
    import os
    import fcntl
    flags = fcntl.fcntl(sys.stdin.fileno(), fcntl.F_GETFL)
    fcntl.fcntl(sys.stdin.fileno(), fcntl.F_SETFL, flags | os.O_NONBLOCK)
except ImportError:
    # Windows 配置非阻塞(需提前安装pywin32)
    import win32file
    win32file.SetNamedPipeHandleState(sys.stdin.fileno(), win32file.PIPE_NOWAIT, None, None)

while True:
    try:
        data = sys.stdin.buffer.read()
        if data:
            print(f"Got {len(data)} bytes", flush=True)
        time.sleep(0.1)  # 降低空循环的CPU占用
    except BlockingIOError:
        # 无数据可读时继续循环
        time.sleep(0.1)
    except Exception:
        break  # 管道关闭或出错时退出

核心注意事项

  • Qt端必须调用QProcess::flush(),确保发送的数据立即写入管道,而非滞留在Qt内部缓冲区。
  • Python端输出时要加flush=True,避免输出被系统缓冲,导致Qt端无法实时获取响应。
  • 若传输数据量极大,可适当调大单次读取的字节上限(比如将1024改为4096),无需固定死缓冲区大小。

内容的提问来源于stack exchange,提问作者Kirill Didkovsky

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 06:20:52