QProcess 无法通过 QPushButton 执行终端行命令

QProcess fails to execute a terminal line command via QPushButton

我试图在我的 gui 上按下 QPushButton 后立即使用 QProcess 执行命令行。 我遇到的问题.sh 可执行文件从未执行过。

我尝试执行的脚本非常简单,报告如下:

#!/bin/bash
echo "try one two three"
rostopic echo -b LaserScan_PointCloud2_test.bag -p /scan > laserScan_test_1.csv

激活按钮功能如下:

filterpcdinterface.h

private slots:
    void on_executeScriptBtn_clicked();
private:
    QProcess *executeBash;

filterpcdinterface.cpp

FilterPCDInterface::FilterPCDInterface(QNode *node, QWidget *parent) :
    qnode(node), 
    QMainWindow(parent),
    ui(new Ui::FilterPCDInterface)
{
    ui->setupUi(this);
    executeBash = new QProcess;
    executeBash->setProcessChannelMode(QProcess::MergedChannels);
    connect(executeBash, &QProcess::readyReadStandardOutput, [this] {
    qDebug() << "This is the output from the process: ";
      on_executeScriptBtn_clicked();
    });
}


void FilterPCDInterface::on_executeScriptBtn_clicked()
{
  executeBash->waitForFinished();
  QString script("/home/emanuele/Desktop/bags/test.sh");
  executeBash->start("sh",QStringList() << script);

  if(!executeBash->waitForStarted()) //default wait time 30 sec
      qWarning() << " cannot start process ";

  int waitTime = 60000 ; //60 sec
  if (!executeBash->waitForFinished(waitTime))
           qWarning() << "timeout .. ";

  executeBash->setProcessChannelMode(QProcess::MergedChannels);
  QString str(executeBash->readAllStandardOutput());
}

到目前为止,我已经咨询了几个 post,但其中 none 帮助我解决了问题。 我偶然发现了 this one and also this one,我从中得到了灵感。

作为口译员,我尝试了 "/bin/sh""sh",但其中 none 给出了预期的结果。 准确地说,这两个我都试过了:

  executeBash->start("sh",QStringList() << script);

  executeBash->start("/bin/sh",QStringList() << script);

但是什么也没发生。

我终于发现了 非常有用 post 这实际上帮助我设置了整个按钮功能,但是当执行脚本时,这次也没有任何反应。

我不确定这种奇怪的行为是否是由构造函数中的 connect 函数引起的。问题还在于 qDebug() 语句也从未达到。

official documentation 提到了使用 startDetached 语句的可能性,但我不确定它是否与我想要实现的目标完全相关。 官方文档总是报告以下声明 here

Unix: The started process will run in its own session and act like a daemon.

因此我认为有一个进程会话在工作并且可以执行,但事实并非如此。

总而言之:我一直在研究问题可能是什么,但我一直遗漏一些我看不到的东西。请指出正确的方向,以帮助解决这个问题,有没有人碰巧遇到同样的问题。

试试这个:

header:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QProcess>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_executeScriptBtn_clicked();

private:
    Ui::MainWindow *ui;
    QProcess    * executeBash;
};
#endif // MAINWINDOW_H

来源:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->executeBash = new QProcess(this);
    this->executeBash->setProcessChannelMode(QProcess::MergedChannels);
    connect(this->executeBash, &QProcess::readyReadStandardOutput, [script = this->executeBash](){
        qDebug() << "[EXEC] DATA: " << script->readAll();
    });
    connect(this->executeBash, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
          [script = this->executeBash](int exitCode, QProcess::ExitStatus exitStatus){
        qDebug() << "[EXEC] FINISHED: " << exitCode << exitStatus;
        if(script->bytesAvailable() > 0)qDebug() << "[EXEC] buffered DATA:" << script->readAll();
    });
    connect(this->executeBash, &QProcess::errorOccurred, [script = this->executeBash](QProcess::ProcessError error){
        qDebug() << "[EXEC] error on execution: " << error << script->errorString();
    });

}
void MainWindow::on_executeScriptBtn_clicked()
{
    qDebug() << "Button clicked!"; // if you don't see this message check your SIGNAL/SLOT connections!
    //this->executeBash->execute(...) // <- will wait till script is finished and block main thread
    this->executeBash->start(QStringLiteral("/bin/sh"), QStringList() << QStringLiteral("/home/emanuele/Desktop/bags/test.sh")); //will start new process without blocking
}

MainWindow::~MainWindow(){delete ui;}