QProcess does not properly trigger executable .sh

Viewed 48

Probelm: I have been trying to run an executable file using QProcess triggering the executable file using a QPushButton and showing the whole result of the output on QTextEdit but without success.

*The error: I don't see the whole output despite, following the official documentation I used this->executeJuliaCheck->readAllStandardOutput()

I have an executable file called check_julia.sh which is located in /home/esoMars/Alignsys/scripts/check_julia.sh which is in the qrc folder of a standard Qt5 project. The file is very simple and is below:

#!/bin/bash

echo "Checking"
cd /home/esoMars/julia-1.7.3/bin
julia

If I type on my home folder the command (base) eso@eso-Oryx-Pro:~$ julia the folloing output appears:

   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.7.3 (2022-05-06)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
|__/                   |

julia> 

All this happens because I use the command line.

Desired goal: I would like NOT to use a command line, but rather I am trying to use a small graphical user interface where to show the output of the same command(base) eso@eso-Oryx-Pro:~$ julia

The way I am doing it is by using a QPushButton that check if julia is installed and show the output on a QTextEdit.

Below what I have done so far:

main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

mainwindow.h

#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();
    void check_julia_installation();

private slots:
    void on_juliaCheckBtn_clicked();

private:
    Ui::MainWindow *ui;
    QProcess *executeJuliaCheck;
    void executeJulia(QString command);
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
#include <QDir>
#include <QStringLiteral>
#include <iostream>

using namespace std;

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // Check Julia Installation
    check_julia_installation();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::check_julia_installation()
{
    // Execution of the QProcess
    this->executeJuliaCheck = new QProcess(this);
    this->executeJuliaCheck->setProcessChannelMode(QProcess::MergedChannels);
    QObject::connect(this->executeJuliaCheck, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
            [this](int exitCode, QProcess::ExitStatus exitStatus){
            qDebug() << "CODE " << exitCode << exitStatus;

                if(exitCode == 0)
                {
                    QString stdOutput = QString::fromUtf8(this->executeJuliaCheck->readAllStandardOutput());
                    qDebug() << stdOutput;
                    ui->textEdit->setText(stdOutput);
                    ui->outputLineEdit->setText("SUCCESS: JULIA IS PROPERLY INSTALLED");
                }
                else
                {
                    QString stdErr = QString::fromUtf8(this->executeJuliaCheck->readAllStandardError());
                    qDebug() << stdErr;
                    QString stdOutput = QString::fromUtf8(this->executeJuliaCheck->readAllStandardOutput());
                    qDebug() << stdOutput;
                    ui->textEdit->setText(stdErr + "\n" + stdOutput);
                    ui->outputLineEdit->setText("CONNECTION ERROR: JULIA NOT PRESENT");
                }
                ui->juliaCheckBtn->setEnabled(true);
    });
}


void MainWindow::on_juliaCheckBtn_clicked()
{
  this->executeJuliaCheck->start("sh",QStringList() << "-c" << "echo /home/esoMars/Alignsys/scripts/check_julia.sh");

  if(! this->executeJuliaCheck->waitForStarted()) //default wait time 30 sec
      qWarning() << " cannot start process ";

  int waitTime = 60000 ; //60 sec
  if (! this->executeJuliaCheck->waitForFinished(waitTime))
           qWarning() << "timeout .. ";
  this->executeJuliaCheck->waitForFinished();

ui->juliaCheckBtn->setEnabled(true);

}

Updates

A user suggested to reduce the clicked button to the following statement. I tried that but unfortunately the QProcess does not do anything:

void MainWindow::on_juliaCheckBtn_clicked()
{
    this->executeJuliaCheck->waitForStarted();
    this->executeJuliaCheck->start("sh",QStringList() << "-c" << "echo /home/esoMars/Alignsys/scripts/check_julia.sh");
    ui->juliaCheckBtn->setEnabled(true);
}

I looked up QProcess quite a while before writing and searched a lot. I found quite a few posts that I read and studied to understand the problem. One post suggested to look at setWorkingDirectory which I did but that didn't help much.

Another posts suggested to use for waitForFinished() just in case other processes are running but it is not my case. Despite a clean exit I don't see the whole output. However, for debugging reasons I put this->executeJuliaCheck->start("sh",QStringList() << "-c" << "echo /home/esoMars/Alignsys/scripts/check_julia.sh"); so that I could confirm the executable file read. However, I still can't see the whole output

I looked also at additional posts such as this one but I still could not figure out how to show the whole output.

Thanks for pointing in the right direction.

1 Answers

I believe you want to see the Julia banner in order to show it to the user. The problem is that once started, the Julia process is waiting for the input.

This can be simply circumvented as:

$ echo "exit()" | julia --banner=yes
               _
   _       _ _(_)_     |  Documentation: https://docs.julialang.org
  (_)     | (_) (_)    |
   _ _   _| |_  __ _   |  Type "?" for help, "]?" for Pkg help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 1.8.0 (2022-08-17)
 _/ |\__'_|_|_|\__'_|  |  Official https://julialang.org/ release
|__/                   |

$

The above command produces the banner (so you can collect it by reading the standard output of your process) and then immediately exits.

Related