QProcess实现进程通信

86 篇文章 1 订阅

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_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 <QMainWindow>
#include <QProcess>
#include <QtWidgets>
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 <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));

}

在这里插入图片描述

  • 7
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 16
    评论
### 回答1: QProcessQt框架中的一个类,用于在一个进程中启动和控制外部程序。它提供了一种进程间通信的机制,使得父进程可以与子进程进行数据的交换和通信。 使用QProcess进行进程间通信可以通过以下步骤实现: 1. 创建一个QProcess对象,可以通过构造函数主动创建,或者通过new运算符动态创建一个对象。 2. 设置要启动的外部程序的路径和命令行参数,可以通过setProgram()和setArguments()函数来实现。 3. 可选择设置一些其它属性,例如工作目录(setWorkingDirectory())、环境变量(setEnvironment())等。 4. 调用start()函数启动子进程。在启动后,子进程会自动运行,并根据程序的执行结果发出相应的信号。 5. 通过信号和槽机制,父进程可以与子进程进行通信。例如,可以通过readyRead()信号和readAll()函数来读取子进程的标准输出信息,也可以通过write()函数向子进程的标准输入写入数据。 6. 子进程执行完毕后会发出相应的finished()信号,可以通过connect()函数将此信号连接到一个槽函数,从而实现对子进程的处理。 通过以上步骤,可以实现父进程与子进程之间的通信。例如,可以通过QProcess启动一个外部程序,然后通过读取子进程的输出信息来获取一些结果,或者通过向子进程的标准输入写入数据来实现交互。 总而言之,QProcess提供了一种简单而灵活的进程间通信机制,使得父进程能够方便地与子进程进行数据交换和通信。同时,QProcess还提供了一些其它的接口函数,用于控制和监控子进程的执行状态,以及设置各种属性,提高了进程通信的灵活性和可扩展性。 ### 回答2: `QProcess`是Qt中用于控制子进程的类。它不仅可以执行外部的可执行文件,还可以与其进行进程间通信。 `QProcess`中的进程通信功能可以通过以下几种方式实现: 1. 通过输入输出:`QProcess`提供了标准输入、标准输出和标准错误输出的接口,可以通过这些接口实现与子进程之间的通信。通过`write()`函数可以向子进程发送数据,而通过`readyRead()`信号则可以接收子进程发送的数据。 2. 通过信号与槽:`QProcess`还提供了`finished()`信号,当子进程退出时会发出该信号。我们可以连接这个信号来执行一些特殊的操作,比如在子进程退出后进行一些清理工作。 3. 通过环境变量:子进程可以通过使用`processEnvironment()`函数获取`QProcess`的环境变量,从而与主进程共享一些配置信息。 总之,借助于`QProcess`,我们可以很方便地实现进程间的通信。无论是通过发送和接收数据、使用信号与槽机制还是共享环境变量,`QProcess`都提供了灵活的接口,让我们可以轻松实现进程间的通信需求。
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东方忘忧

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值