QProcess 无法通过 QPushButton 执行终端行命令 [英] QProcess fails to execute a terminal line command via QPushButton

查看:127
本文介绍了QProcess 无法通过 QPushButton 执行终端行命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在我的 gui 上按下 QPushButton 后立即使用 QProcess 执行命令行.问题我的问题是 .sh 可执行文件永远不会被执行.

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.

作为解释器,我尝试了 "/bin/sh""sh" 但它们都没有给出预期的结果.准确地说,我尝试了这两个:

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

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

但什么也没发生.

我终于看到这篇非常有用的帖子,它实际上帮助我设置整个按钮功能,但是到了执行脚本的时候,这次也没有任何反应.

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.

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

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.

官方文档 提到了使用 startDetached 声明,但我不确定它是否与我想要实现的完全相关.总是官方文档报告以下声明here

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:启动的进程将在它自己的会话中运行并表现得像一个守护进程.

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.

推荐答案

试试这个:

标题:

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

这篇关于QProcess 无法通过 QPushButton 执行终端行命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆