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

问题描述 投票:0回答:1

我试图用 QProcess 只要我一按 QPushButton 在我的gui上。问题是 我有的是 .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());
}

到目前为止,我已经咨询了几个帖子,但他们没有帮助我解决这个问题。这个这个 其实我的想法就来自于此。

作为翻译,我尝试了两个 "/bin/sh""sh" 但都没有得到预期的结果.准确地说,我同时尝试了这个。

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

和...

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

但什么也没发生。

我终于遇到了 这个 非常有用的帖子,它实际上帮助我设置了整个按钮功能,但当它是执行脚本的时候,这次也没有发生任何事情。

我不知道这种奇怪的行为是否是因 connect 函数的构造函数中。问题还在于 qDebug() 声明也从未达成。

公文 提到可以使用 startDetached 但我不确定它是否能与我所要实现的目标完全相关。此处

Unix。启动的进程会在自己的会话中运行,就像一个守护进程一样。

因此,我认为有一个进程会话在工作,可以执行,但它不是。

总而言之。我一直在研究问题所在 但我一直在寻找一些我没有看到的东西。请指出正确的方向来帮助解决这个问题,如果有人碰巧有同样的问题。

c++ bash qt qt5 qprocess
1个回答
1
投票

试试这个。

头:

#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;}
© www.soinside.com 2019 - 2024. All rights reserved.