【问题标题】:How to communicate Qt applications two-way如何双向通信 Qt 应用程序
【发布时间】:2018-03-21 14:46:26
【问题描述】:

我想在我的 Qt 应用程序之间创建双向通信。我想使用 QProcess 来做到这一点。我从根应用程序成功调用子应用程序并发送测试数据而没有任何错误,但我无法在子应用程序中接收任何数据。我将不胜感激任何帮助。我正在使用 Qt 4.7.1。在我的测试代码下面:

根应用:

InterProcess::InterProcess(QObject *parent) : QProcess(parent)
{
    process = new QProcess(this);
    process->start(myChildApp);
    process->waitForStarted();
    process->setCurrentWriteChannel(QProcess::StandardOutput);
    process->write("Test");

    connect( process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(error(QProcess::ProcessError)) );
    connect( process, SIGNAL(readyReadStandardError()), this, SLOT(readyReadStandardError()) );
    connect( process, SIGNAL(readyReadStandardOutput()), this, SLOT(readyReadStandardOutput()) );     

QByteArray InterProcess::read()
{
    QByteArray readBuffer = process->readAllStandardOutput();
    return readBuffer;
}

void InterProcess::error( QProcess::ProcessError error )
{
    qDebug() << "Error!";
    qDebug() << error;
}

void InterProcess::readyReadStandardError()
{
    qDebug() << "Ready to read error.";
    qDebug() << process->readAllStandardError();
}

void InterProcess::readyReadStandardOutput()
{
    qDebug() << "The output:";
    QByteArray readBuffer = process->readAllStandardOutput();
    qDebug() << readBuffer;
}

子应用:

InterProcess::InterProcess(QObject *parent) : QProcess(parent)
{
    process = new QProcess();
    process->setCurrentReadChannel(QProcess::StandardOutput);

    connect( process, SIGNAL(readyRead()), this, SLOT(readyReadStandardOutput()));
    connect( process, SIGNAL(error(QProcess::ProcessError)), this, SLOT(error(QProcess::ProcessError)) );
    connect( process, SIGNAL(readyReadStandardError()), this, SLOT(readyReadStandardError()) );
    connect( process, SIGNAL(readyReadStandardOutput()), this, SLOT(readyReadStandardOutput()) );

    process->waitForReadyRead(5000);
}

void InterProcess::readyReadStandardError()
{
    qDebug() << "Ready to read error.";
    qDebug() << process->readAllStandardError();
    setText("REady error");
}

void InterProcess::readyReadStandardOutput()
{
    setMessage("2");
    qDebug() << "The output:";
    QByteArray readBuffer = process->readAllStandardOutput();
    qDebug() << readBuffer;
}
void InterProcess::error( QProcess::ProcessError error )
{
    qDebug() << "Error!";
    qDebug() << error;
    setText(QString(error));
}

【问题讨论】:

  • 嗯...我试试看。
  • 我不确定我是否理解您要在子应用中执行的操作。您创建一个QProcess 并修复一些连接等。但你永远不会将它与任何进程相关联。如果我遗漏了一些明显的东西,我们深表歉意。
  • 在子应用程序中,我想从根应用程序读取消息。我在这里做错了什么?它必须在 Windows 和 Linux 上运行。我之前阅读了 qt 文档,在我的情况下,我应该使用它来通信 QProcess 或 TCP/IP。共享内存对我来说不是最好的解决方案。

标签: qt qprocess qiodevice


【解决方案1】:

很难在一个答案中解释所有错误,因此只需查看代码并询问您是否仍有问题。 这是使用 QProcess 作为 IPC 的示例。

这是你的主要进程,它创建额外的进程并连接到它的信号

MyApplicaiton.h

#ifndef MYAPPLICATION_H
#define MYAPPLICATION_H
#include <QApplication>

class InterProcess;
class MyApplication : public QApplication {
    Q_OBJECT
public:
    MyApplication(int &argc, char **argv);
signals:
    void mainApplicationSignal();
private slots:
    void onInterProcessSignal();
private:
    InterProcess *mProcess;
};
#endif // MYAPPLICATION_H

MyApplicaiton.cpp

#include "MyApplication.h"
#include "InterProcess.h"

MyApplication::MyApplication(int &argc, char **argv) : QApplication(argc, argv) {
    mProcess = new InterProcess(this);
    connect(mProcess, SIGNAL(interProcessSignal()),
            this, SLOT(onInterProcessSignal()));
    mProcess->start();
}

void MyApplication::onInterProcessSignal() {}

这是您的 interProcess 类的示例实现:

InterProcess.h

class InterProcess : public QProcess {
    Q_OBJECT
public:
    explicit InterProcess(QObject *parent = nullptr);
signals:
    void interProcessSignal();
private slots:
    void onMainApplicationSignal();
};

InterProcess.cpp

#include "InterProcess.h"
#include "MyApplication.h"


InterProcess::InterProcess(QObject *parent) : QProcess(parent) {
    if(parent) {
        auto myApp = qobject_cast<MyApplication *>(parent);
        if(myApp) {
            connect(myApp, SIGNAL(mainApplicationSignal()),
                    this, SLOT(onMainApplicationSignal()));
        }
    }
}

void InterProcess::onMainApplicationSignal() {}

【讨论】:

  • 它工作!你的例子改变了我的想法。在我的情况下,更好的解决方案是使用 QNetwork 类在应用程序之间创建 TCP/IP 双向通信。非常感谢。
  • @user8510613 我认为是的。我记不太清楚了,但在我写这个答案之前,我用 msys2 和 mingw64 在 windows 上检查了这段代码。
【解决方案2】:

在本地,使用UDP非常方便高效

void Server::initSocket() {
  udpSocket = new QUdpSocket(this);
  udpSocket->bind(QHostAddress::LocalHost, 7755);
  connect(udpSocket, SIGNAL(readyRead()), this, SLOT(readPendingDatagrams()));}


void Server::readPendingDatagrams(){
  while (udpSocket->hasPendingDatagrams()) {
      QByteArray datagram;
      datagram.resize(udpSocket->pendingDatagramSize());
      QHostAddress sender;
      quint16 senderPort;

      udpSocket->readDatagram(datagram.data(), datagram.size(),
                              &sender, &senderPort);

      processTheDatagram(datagram);
  }}

【讨论】:

  • 答案不能完全基于离线资源
  • 本地使用UDP或TCP非常方便。非常感谢。
猜你喜欢
  • 1970-01-01
  • 2013-02-11
  • 1970-01-01
  • 1970-01-01
  • 2019-05-19
  • 2018-09-13
  • 2014-06-30
  • 2012-01-27
  • 1970-01-01
相关资源
最近更新 更多