QProcess fails to execute a terminal line command via QPushButton

自作多情 提交于 2021-01-29 05:52:08

问题


I am trying to execute a command line using QProcess as soon as I push a QPushButton on my gui. The problem I have is that the .sh executable file is never executed.

The script I am trying to execute is very simple and reported below:

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

Below the function that activate the button:

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());
}

So far I have been consulting several posts but none of them helpd me solve the problem. I came across this one and also this one from which I actually got the idea.

As interpreter I tried both "/bin/sh" and "sh" but none of them gave the expected result. To be precise I tried both this one:

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

and

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

But nothing happened.

I finally came across this very useful post which actually helped me set up the whole button function, but when it was time to execute the script nothing happens this time too.

I am not sure if this strange behavior is caused by the connect function in the constructor. The problem is also that the qDebug() statement is also never reached.

The official documentation mention the possibility to use a startDetached statement but I am not sure it can fully relate to what I am trying to achieve. Always the official documentation reports the following statement here

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

And therefore I thought that there was a process session working and that could be executed but it is not.

In conclusion: I have been researching a lot what the problem might be but I keep missing something I don't see. Please point to the right direction to help solving this issue is anyone happened to have the same problem.


回答1:


Try this:

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

source:

#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;}


来源:https://stackoverflow.com/questions/61762309/qprocess-fails-to-execute-a-terminal-line-command-via-qpushbutton

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!