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;}
我试图在我的 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);
但是什么也没发生。
我终于发现了
我不确定这种奇怪的行为是否是由构造函数中的 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;}