简体   繁体   English

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

[英]QProcess fails to execute a terminal line command via QPushButton

I am trying to execute a command line using QProcess as soon as I push a QPushButton on my gui.我试图在我的 gui 上按下QPushButton后立即使用QProcess执行命令行。 The problem I have is that the .sh executable file is never executed.我遇到的问题.sh可执行文件永远不会执行。

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:在激活按钮的 function 下方:

filterpcdinterface.h过滤器pcd接口.h

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

filterpcdinterface.cpp过滤器pcd接口.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.作为解释器,我尝试了"/bin/sh""sh" ,但它们都没有给出预期的结果。 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.我终于看到了这篇非常有用的帖子,它实际上帮助我设置了整个按钮 function,但是当是时候执行脚本时,这次也没有任何反应。

I am not sure if this strange behavior is caused by the connect function in the constructor.我不确定这种奇怪的行为是否是由构造函数中的connect function 引起的。 The problem is also that the qDebug() statement is also never reached.问题还在于qDebug()语句也永远不会到达。

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.官方文档提到了使用startDetached语句的可能性,但我不确定它是否与我想要实现的目标完全相关。 Always the official documentation reports the following statement here官方文档总是在这里报告以下声明

Unix: The started process will run in its own session and act like a daemon. Unix:启动的进程将在自己的 session 中运行,并像守护进程一样运行。

And therefore I thought that there was a process session working and that could be executed but it is not.因此我认为有一个进程 session 正在工作并且可以执行,但事实并非如此。

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.请指出正确的方向以帮助解决此问题,是否有人碰巧遇到同样的问题。

Try this:尝试这个:

header: 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;}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM