Qt中QProcess无需重启子进程多次写入数据的实现方法
Qt C++父进程多次向Python子进程发送数据的解决方案
问题本质
你碰到的问题核心在于:
- Python里
for line in sys.stdin这种写法,会一直阻塞,直到读到换行符或者输入流被关闭(也就是父进程调用closeWriteChannel()发送EOF)才会返回内容 - 不调用
closeWriteChannel()时,QProcess的输出缓冲区没刷新,数据没真正传到子进程的stdin,所以Python收不到 - 但关了写入通道就没法再给子进程发数据,这就导致只能发一次
解决方法(不用关通道,不用重启进程)
1. 父进程(Qt C++):发送后确保数据写入管道
别再调用closeWriteChannel(),改成每次发完数据后调用waitForBytesWritten(),同时每次发送的内容结尾加上换行符——这样Python那边能触发行读取,不用等EOF。
修改后的父进程代码:
if(PythonProcess.state() == QProcess::Running){ // 第一次发送 QString data1 = "starttttttttttttttt123"; PythonProcess.write(data1.toUtf8()); // 用QByteArray直接转比std::string更简洁 PythonProcess.write("\n"); // 必须加换行,让Python知道这是一行的结尾 PythonProcess.waitForBytesWritten(); // 等待数据真正写入管道,避免留在缓冲区 // 第二次发送(通道保持开放,直接发就行) QString data2 = "newwwwwoneeee"; PythonProcess.write(data2.toUtf8()); PythonProcess.write("\n"); PythonProcess.waitForBytesWritten(); }
2. 子进程(Python):修正读取逻辑
你原来的嵌套循环有问题:while True套for line in sys.stdin,第一次读到EOF后for循环会结束,外层while再进去时,for line会一直阻塞。改成直接用readline()循环读取,每次有换行就会触发。
修改后的子进程代码:
import sys while True: line = sys.stdin.readline() if not line: # 如果输入流被关闭(父进程退出),就退出循环 break # 打印收到的内容,strip()去掉换行符 print(f"收到: {line.strip()}")
补充说明
waitForBytesWritten()是阻塞到数据写入系统管道,确保子进程能及时拿到数据,避免QProcess的缓冲区积压- 一定要加换行符,这是Python行读取的触发条件;如果要发二进制数据或者不带换行的内容,可以自定义分隔符(比如用
\0作为结束标志),然后Python那边按分隔符拆分读取 - 测试时可以在父进程里加个按钮,每次点击就发一次数据,看子进程能不能实时收到
内容的提问来源于stack exchange,提问作者rohan099
相关产品推荐
相关产品推荐

