QProcess实现进程通信的方式有点类似于管道。
QProcess父进程通过write来写入标准输入stdin,通过ReadyRead信号来接收子进程的消息。
QProcess子进程通过QFile来读取标准输入来接收父进程信息。通过QFile绑定QSocketNotifier来接收标准输入的实时信号,因为QSocketNotifier的activated信号可以通过标准输入是否有消息实时触发。
QProcess子进程通过QFile绑定标准输出stdout来发送消息给父进程。
注意:子进程读取信息不能通过QFile的readline等接口读取父进程信息,因为QFile他会读取标准输入的所有信息,并且不到长度就没有返回。哪怕QFile设置了读取长度,也会在满足长度后才有消息返回,我也不知为啥会这样。所有需要通过unstd.h的read接口来读取标准输入。
父进程:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QProcess>
#include <QtWidgets>namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = nullptr);~MainWindow();private slots:void slotopenprocess();void slotsenddata();void slotfinish(int code);void slotreaddata();
private:Ui::MainWindow *ui;QPushButton* m_btn;QPushButton* m_sendbtn;QLineEdit* m_edit;QTextEdit* m_readedit;QProcess* m_process;
};#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);this->setWindowTitle("server");m_btn = new QPushButton("打开进程",this->centralWidget());m_sendbtn = new QPushButton("发送",this->centralWidget());m_edit = new QLineEdit(this);m_readedit = new QTextEdit(this);m_process = new QProcess(this);QVBoxLayout* lay = new QVBoxLayout(this);lay->addWidget(m_btn);lay->addWidget(m_edit);lay->addWidget(m_sendbtn);lay->addWidget(m_readedit);lay->addWidget(m_sendbtn);this->centralWidget()->setLayout(lay);connect(m_btn,SIGNAL(clicked()),this,SLOT(slotopenprocess()));connect(m_sendbtn,SIGNAL(clicked()),this,SLOT(slotsenddata()));connect(m_process,SIGNAL(finished(int)),this,SLOT(slotfinish(int)));connect(m_process,SIGNAL(readyRead()),this,SLOT(slotreaddata()));
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::slotopenprocess()
{m_process->start("/home/yjd/yjd/test/myprocess/myprocess");
}void MainWindow::slotsenddata()
{if (m_process->isOpen())m_process->write(m_edit->text().toUtf8());
}void MainWindow::slotfinish(int code)
{qWarning()<<"process finish"<<code<<m_process->readAllStandardOutput();
}void MainWindow::slotreaddata()
{m_readedit->append(QString("接收消息:%1").arg(m_process->readAllStandardOutput().data()));
}
子进程:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QProcess>
#include <QtWidgets>
namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{Q_OBJECTpublic:explicit MainWindow(QWidget *parent = nullptr);~MainWindow();private slots:void slotopenprocess();void slotsenddata();void slotfinish(int code);void slotreaddata(int fd);
private:Ui::MainWindow *ui;QPushButton* m_btn;QPushButton* m_sendbtn;QLineEdit* m_edit;QTextEdit* m_readedit;QProcess* m_process;QSocketNotifier* m_clientsocket;QFile m_file;
};#endif // MAINWINDOW_H
#include "mainwindow.h"
#include <unistd.h>
#include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{ui->setupUi(this);this->setWindowTitle("client");m_btn = new QPushButton("打开进程",this->centralWidget());m_sendbtn = new QPushButton("发送",this->centralWidget());m_edit = new QLineEdit(this);m_readedit = new QTextEdit(this);m_process = new QProcess(this);QVBoxLayout* lay = new QVBoxLayout(this);lay->addWidget(m_btn);lay->addWidget(m_edit);lay->addWidget(m_sendbtn);lay->addWidget(m_readedit);lay->addWidget(m_sendbtn);this->centralWidget()->setLayout(lay);connect(m_btn,SIGNAL(clicked()),this,SLOT(slotopenprocess()));connect(m_sendbtn,SIGNAL(clicked()),this,SLOT(slotsenddata()));connect(m_process,SIGNAL(finished(int)),this,SLOT(slotfinish(int)));
}MainWindow::~MainWindow()
{delete ui;
}void MainWindow::slotopenprocess()
{m_file.open(stdin, QFile::ReadOnly);if (m_file.isOpen()){m_clientsocket = new QSocketNotifier(m_file.handle(), QSocketNotifier::Read,this);connect(m_clientsocket,SIGNAL(activated(int)),this,SLOT(slotreaddata(int)));QMessageBox::information(this,"title","open success");}
}void MainWindow::slotsenddata()
{QFile file;file.open(stdout, QFile::WriteOnly);file.write(m_edit->text().toUtf8());
}void MainWindow::slotfinish(int code)
{qWarning()<<"process finish"<<code<<m_process->readAllStandardOutput();
}void MainWindow::slotreaddata(int fd)
{if(fd != m_file.handle() )return;char buf[128] = {0};read(fd,buf,sizeof(buf)); //不建议使用m_file.readLine(5)来读取返回值m_readedit->append(QString::fromUtf8("接收消息:%1").arg(buf));}