QProcess实现进程通信

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 
#include 
#include 

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    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 
#include 
#include 
namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    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 
#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));

}

QProcess实现进程通信_第1张图片

你可能感兴趣的:(QT,c/c++,qt,qt5)