QProcess 클래스 사용

QProcess Class는 외부 프로그램을 실행시킬 수 있고, 현재 프로그램과 외부 프로그램 간 Communication을 지원합니다.

system() 함수와 비슷한 역할을 하는 Qt Class입니다.

 

QProcess Class를 통해서 로컬에 있는 프로그램 뿐만 아니라 다른 시스템의 프로그램도 SSH(Secure Shell Protocol) 통신만 가능하다면 제어할 수 있습니다. 외부 프로그램을 실행하여 출력 값을 현재 실행 중인 프로그램의 textBrowser에 출력하는 프로그램을 구현했습니다.

 

외부 프로그램 실행 후 QProcess 객체와 해당 프로그램에서 결과 값의 출력을 확인 할 수 있는 Signal/Slot 시스템을 구축해주어야 합니다.

QProcess process;
QObject::connect(textMsgProcess,  SIGNAL(readyReadStandardOutput()), this, SLOT(PrintMsg()));  

 

이후 외부 프로그램의 결과 값이 출력될 때마다 readyReadStandardOutput()의 signal이 발생하여 PrintMsg()의 Slot이 호출됩니다.

slot에서는 결과 값을 textBrowser로 출력하기 때문에 실시간으로 외부 프로그램의 값을 볼 수 있습니다. 

 

로컬 외부 프로그램 실행

로컬 환경에서 뿐만아니라 다른 시스템의 프로그램의 결과 값도 제어가 가능하다고 위에서 말했다시피, 아래의 명령어를 이용하면 접근이 가능합니다. pipe의 buffer를 강제로 비워 외부 프로그램의 출력 값을 바로 가져오기 위해 "stdbuf -oL"을 사용합니다.

QProcess process;
process.start("stdbuf -oL [프로그램 절대경로]");
process.waitForFinished();

 

QProcess는 쉘 명령을 지원하지 않습니다. 따라서 파이프 기호는 쉘에 의해 해석되지 않습니다.

쉘 명령어를 QProcess로 실행시킬 경우 아래와 같은 형식으로 명령어를 사용해야 합니다.

QProcess process;
process.start("sh", QStringList() << "-c" << "쉘 명령어");
process.waitForFinished();

 

다른 시스템 외부 프로그램 실행

다른 시스템의 외부 프로그램을 ssh를 통해 실행해야 할 경우 아래와 같은 형식으로 사용할 수 있습니다.

sshpass로 연결할 때 사용자의 입력을 기다리지 않고 파라미터 또는 파일을 통해 입력받은 암호를 이용하여 연결하여 사용합니다.

QProcess process;
process.start("sshpass -p root ssh root@[ip주소] stdbuf -oL [프로그램 절대경로]");
process.waitForFinished();

 

// Main Loop

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
 60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
 
#include <QMainWindow>
#include <QProcess>
 
namespace Ui {
class MainWindow;
}
 
class MainWindow : public QMainWindow
{
    Q_OBJECT
 
public:
    explicit MainWindow(QWidget *parent = 0);
    void ExecuteProgram();
    ~MainWindow();
 
private slots:
    void PrintMsg();
 
private:
    Ui::MainWindow *ui;
    QProcess *textMsgProcess;
};
 
#endif // MAINWINDOW_H
 
 
// mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
 
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
 
    textMsgProcess = new QProcess(this);
    QObject::connect(textMsgProcess,  SIGNAL(readyReadStandardOutput()), this, SLOT(PrintMsg()));   
    ExecuteProgram();
}
 
MainWindow::~MainWindow()
{
    delete ui;
}
 
void MainWindow::PrintMsg()
{
    QByteArray data;
    data = textMsgProcess->readAllStandardOutput();
    ui->textBrowser->insertPlainText(data);
    ui->textBrowser->moveCursor(QTextCursor::End);
    data.clear();
}
 
void MainWindow::ExecuteProgram()
{
    QString program = QString("/home/build-Message_Program-Desktop_Qt_5_8_0_GCC_64bit-Debug/Message_Program");
    textMsgProcess->start(program);
 
    if(textMsgProcess->waitForStarted() == false)
    {
        ui->textBrowser->insertPlainText("External Program Starting Error\n");
    }
    else
    {
        ui->textBrowser->insertPlainText("External Program Started\n");
    }
}
 

 

// External Program

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <unistd.h>
 
using namespace std;
 
int main(int argc, char *argv[])
{
    for(int i = 0; i < 20; i++)
    {
        cout << "Hello World!" << endl;
        sleep(1);
    }
    return 0;
}

 

// Result Image