Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QProcess: start a compiled c program and output to textBrowser in Linux



  • I have search and looked at other examples but nothing seems to work.
    Here are where I've referred to:
    http://www.qtforum.org/article/3079/howto-start-an-external-program-from-a-qt-application.html
    http://doc.qt.io/qt-5/qprocess.html
    and a few others

    Here's what I have in my project:
    mainwindow.h

    #ifndef MAINWINDOW_H
    #define MAINWINDOW_H
    
    #include <QMainWindow>
    
    namespace Ui {
    class MainWindow;
    }
    
    class MainWindow : public QMainWindow
    {
        Q_OBJECT
    
    public:
        explicit MainWindow(QWidget *parent = 0);
        ~MainWindow();
    
    private slots:
        void on_pushButton_clicked();
    
    private:
        Ui::MainWindow *ui;
    };
    
    #endif // MAINWINDOW_H
    

    main.cpp

    #include "mainwindow.h"
    #include <QApplication>
    #include <QPushButton>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWindow w;
        w.show();
    
        return a.exec();
    }
    

    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 proc;
        proc.start("/root/Desktop/a.out");
    
        proc.waitForFinished();
        QString output = proc.readAllStandardOutput();
        ui->textBrowser->setText(output);
    }
    

    mainwindow.ui

    <?xml version="1.0" encoding="UTF-8"?>
    <ui version="4.0">
     <class>MainWindow</class>
     <widget class="QMainWindow" name="MainWindow">
      <property name="geometry">
       <rect>
        <x>0</x>
        <y>0</y>
        <width>683</width>
        <height>519</height>
       </rect>
      </property>
      <property name="maximumSize">
       <size>
        <width>1112</width>
        <height>625</height>
       </size>
      </property>
      <property name="windowTitle">
       <string>MainWindow</string>
      </property>
      <widget class="QWidget" name="centralWidget">
       <widget class="QTextBrowser" name="textBrowser">
        <property name="geometry">
         <rect>
          <x>20</x>
          <y>50</y>
          <width>631</width>
          <height>191</height>
         </rect>
        </property>
       </widget>
       <widget class="QWidget" name="layoutWidget">
        <property name="geometry">
         <rect>
          <x>20</x>
          <y>10</y>
          <width>631</width>
          <height>30</height>
         </rect>
        </property>
        <layout class="QHBoxLayout" name="horizontalLayout">
         <item>
          <widget class="QPushButton" name="pushButton">
           <property name="text">
            <string>Start pcap (100p)</string>
           </property>
          </widget>
         </item>
         <item>
          <spacer name="horizontalSpacer">
           <property name="orientation">
            <enum>Qt::Horizontal</enum>
           </property>
           <property name="sizeHint" stdset="0">
            <size>
             <width>200</width>
             <height>20</height>
            </size>
           </property>
          </spacer>
         </item>
        </layout>
       </widget>
      </widget>
      <widget class="QMenuBar" name="menuBar">
       <property name="geometry">
        <rect>
         <x>0</x>
         <y>0</y>
         <width>683</width>
         <height>25</height>
        </rect>
       </property>
      </widget>
      <widget class="QToolBar" name="mainToolBar">
       <attribute name="toolBarArea">
        <enum>TopToolBarArea</enum>
       </attribute>
       <attribute name="toolBarBreak">
        <bool>false</bool>
       </attribute>
      </widget>
      <widget class="QStatusBar" name="statusBar"/>
     </widget>
     <layoutdefault spacing="6" margin="11"/>
     <resources/>
     <connections/>
    </ui>
    
    

    When I clicked the pushButton nothing happens but if I tried using Linux system's command in the QProcess such as

        QProcess proc;
        proc.start("ls -al");
    
        proc.waitForFinished();
        QString output = proc.readAllStandardOutput();
        ui->textBrowser->setText(output);
    

    It works where in the textBrowser it will list files/folders in the home directory.
    I've also tried with sh -c but still doesn't work.

        proc.start("sh", QStringList() << "-c" << "/root/Desktop/a.out");
    

    Is there way to execute a compiled c program using QProcess?
    I'm at lost



  • Hi, welcome to the forum. Check the ProcessError to get a hint on what went wrong. Also, add a call to waitForStarted and see if it hangs. Judging by the pathname, your a.out is owned by the user root. I assume you're not logged in as root so you probably don't have the sufficient access rights to run that executable.


  • Lifetime Qt Champion

    Hi
    Besides what @Wieland suggests
    did you try open a shell and just type
    /root/Desktop/a.out

    and see if it can run ?

    in some cases it wants
    chmod +x a.out

    to even be allowed to run.
    (normally the compiler / linker does that for you)



  • @Naim , @mrjj
    If you like trivia (you probably don't...), you can actually execute it without the execute bit set via the accepted answer to https://superuser.com/questions/341439/can-i-execute-a-linux-binary-without-the-execute-permission-bit-being-set :)


  • Lifetime Qt Champion

    @JNBarchan
    But does it set the bit ?
    chmod a-x /tmp/ls



  • @Wieland Yes I'm using root. As for ProcessError and waitForStarted I'll reply that later
    @mrjj I compiled a.out as the root user


  • Lifetime Qt Champion

    @Naim
    Ok, so you are logged in as root. so its not just rights issue.
    Hopefully ProcessError tells you why it cant run :)


  • Lifetime Qt Champion

    @Naim: As @mrjj already asked earlier before:

    Can you run /root/Desktop/a.out from the shell? It might be, that /root is on a partition that is mounted as no-executable. Why has to program to reside below /root?


  • Lifetime Qt Champion

    @mrjj said in QProcess: start a compiled c program and output to textBrowser in Linux:

    @JNBarchan
    But does it set the bit ?
    chmod a-x /tmp/ls

    chmod a-x /tmp/ls clears the executable bit ;)


  • Lifetime Qt Champion

    @aha_1980
    ahh of course its -x :)
    my brain said a TO x (facepalm)
    So it can run without it using LD and some magic. Cool.



  • @aha_1980 Yes I can run it in shell with ./root/Desktop/a.out. I'm using the root user on a virtual machine.



  • I may have find the problem here. My C program a.out runs indefinitely and textBrowser only shows the output once my program have finished executing. I've tried to run another C program that accepts command line input to loop how many times. Its output shows up in textBrowser after it has done looping.


  • Qt Champions 2019

    @Naim Use http://doc.qt.io/qt-5/qprocess.html#readyReadStandardOutput and http://doc.qt.io/qt-5/qprocess.html#readyReadStandardError to get notifications each time the process writes something to stdout or stderr and read it using http://doc.qt.io/qt-5/qprocess.html#readAllStandardOutput and http://doc.qt.io/qt-5/qprocess.html#readAllStandardError. Do not call waitForFinished, just make sure your proc does not go out of scope (make it class member).