Solved Run a Terminal Code with QProcess on Ubuntu 18
-
We try to run a command on terminal with QProcess. We don't have to see the terminal but the code should work exacly at the same time with clicking the button. But somehow the code doesnt work, we tried many ways to make it.
Here is our mainwindow.cpp:
#include "mainwindow.h" #include "ui_mainwindow.h" #include <QProcess> MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_pushButton_clicked() { QProcess p; p.setProgram("screen firefox"); // p.setWorkingDirectory("/..."); // if needed p.start(); p.waitForFinished(-1); }
-
We found the solution. roslaunch is a ROS command but we didn't implemented ros.h. We had a ROS implemented example and tried that in it, it worked! All the code was fine but the problem was the library.
Thank you all for your help.
-
@aliemrenebiler
What isscreen firefox
supposed to do, how do we know? You need to put in error checking: slot onto all the signals for errors/finished, and grab any output on stdout/stderr. Then with that information you can figure out what is/is not going on, and ask for help if necessary. -
Hi
Just a note first. p.waitForFinished(-1); will hang your app until "screen" exits which it
normally wont.Anyway, if I run it like this
void MainWindow::RunQProcess( ) { QProcess* process = new QProcess(); QObject::connect(process, &QProcess::started, []() { qDebug() << "started"; }); QObject::connect(process, &QProcess::readyRead, [process]() { QTextStream outputStream(process->readAllStandardOutput()); auto data = outputStream.readAll(); qDebug() << "readyRead:" << data; }); QObject::connect(process, &QProcess::readyReadStandardOutput, [process]() { QTextStream outputStream(process->readAllStandardOutput()); auto data = outputStream.readAll(); qDebug() << "readyReadStandardOutput" << " read:" << data; }); QObject::connect(process, &QProcess::readyReadStandardError, [process]() { QTextStream errorStream(process->readAllStandardError()); auto data = errorStream.readAll(); qDebug() << "readyReadStandardError" << " read:" << data; }); QObject::connect(process, qOverload<int, QProcess::ExitStatus>(&QProcess::finished), [process](int exitCode, QProcess::ExitStatus exitStatus) { auto res = "exitcode:" + (QString::number(exitCode) + " exitStatus:" + QString::number(exitStatus)); qDebug() << "Status:" << res; process->deleteLater(); // clean up }); process->start("screen", QStringList() << "firefox" ); }
I get
started readyRead: "Must be connected to a terminal.\r\n" readyReadStandardOutput read: "" Status: "exitcode:1 exitStatus:0"
so my guess is there is no active TTY in the QProcess inviroment.
-
@JonB It suppose to open the Firefox App. And it does when I write it in terminal. Thanks for your answer.
-
@mrjj Thank you so much. I will try this and write what happened again. We found a way to use terminal commands with QProcess, I will send the final result later.
-
@mrjj We tried your way but there is a problem with qOverload. It is an int we assume but not indentified (use of undeclared identifier). Can you help again?
I would like to explain what we are aiming to do:
We have a folder called "display.launch", it is a Rviz folder that will open with "roslaunch display.launch" command. We basicly open the terminal and go to the direction of /home/said/qt_ws/src/sasi_solid_v12/launch/ and start the "roslaunch display.launch" command. It opens the Rviz model automaticly. We want to do it with a button click on Qt.So as summary:
- We should start a terminal (it can be hidden, no problem)
- Go to the desired direction.
- Start a command ("roslaunch display.launch" or something else...)
-
Hi
for which signal do you need qOverload ?
can you show the line that gives the error ?1:Well that should be ok.
2: you can use
https://doc.qt.io/qt-5/qprocess.html#setWorkingDirectory3: you might need to provide the full path to the roslaunch exe
for Qt to find it. -
@mrjj hi again.
qOverload is a part of the code that you sent us. We really don't know what it does. But it says unclerified so we couldn't make the code work.We already used setWorkingDirectory and that works fine. Thank you.
The problem is we don't need the exe path because roslaunch is a command, not an exe. roslaunch automatically starts the Rviz exe and the folder that we wanna open in Rviz. So the need is not the path, a way to start the roslaunch command.
-
@aliemrenebiler
hi
ah sorry. the eye is the first place one goes blind... ;)QObject::connect(process, qOverload<int, QProcess::ExitStatus>(&QProcess::finished),
https://doc.qt.io/qt-5/qtglobal.html#qOverload
I forgot in which version it came. Maybe your Qt is older.
anyway one can use a cast instead
QObject::connect(process, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), [process](int exitCode, QProcess::ExitStatus exitStatus) { auto res = "exitcode:" + (QString::number(exitCode) + " exitStatus:" + QString::number(exitStatus)); qDebug() << "Status:" << res; process->deleteLater(); // clean up });
qOverload is just syntax sugar to make it read nicer.
-
@aliemrenebiler said in Run a Terminal Code with QProcess on Ubuntu 18:
We really don't know what it does
Then please read documentation (https://doc.qt.io/qt-5/qtglobal.html#qOverload) and include QtGlobal as the documentation shows:
#include <QtGlobal>
-
We found the solution. roslaunch is a ROS command but we didn't implemented ros.h. We had a ROS implemented example and tried that in it, it worked! All the code was fine but the problem was the library.
Thank you all for your help.