QT开发之QProcess进程运行外部程序

Qt提供了一个QProcess类用于启动外部程序并与之通信,启动一个新的进程的操作非常简单,只需要将待启动的程序名称和启动参数传递给start()函数即可.

 当调用start()函数后,myProcess进程立即进入启动状态,但程序ls尚未被调用,不能读写标准输入输出设备.当进程完成启动后就进入"运行状态"并向外发出started()信号.在输入输出方面,QProcess将一个进程看做一个流类型的I/O设备,可以像使用QTcpSocket读写流类型的网络连接一样来读写一个进程.可以通过QIODevice::write()函数向所启动进程的标准输入写数据,也可以通过QIODevice::read()、QIODevice::readLine()和QIODevice::getChar()函数从这个进程的标准输出读数据.此外由于QProcess是从QIODevice类继承而来的,因四级,它也可以作QXmlReader的数据在源,或者为QFtp产生上传数据.最后,当进程退出时QProcess进入起始状态----"非运行状态",并发出finished()


信号在参数中返回了进程退出的退出码和退出状态,可以调用exitCode()函数和exitStatus()函数分别获取最后退出进程的这两个值.其中,Qt定义的进程"退出
状态"只有正常退出和进程崩溃两种,分别对应值QProcess::NormalExit(值0)和QProcess::CrashExit(值1).当进程在运
行中产生错误时,QProcess将发出error()信号,可以通过,调用error()函数返回最后一次产生错误的类型,并通过,state()
找出此时进程所处的状态.Qt定义了如下的进程错误代码:
----------------------------------------------------------------
错误常量                                值       描述
QProcess::FailedToStart        0        进程启动失败
QProcess::Crashed                1        进程成功启动后崩溃
QProcess::Timedout               2        最后一次调用waitFor...()函数超时.此时QProcess状态不变,并可以再次             调waitFor()类型的函数
QProcess::WriteError              3        向进程写入时出错.如进程尚未启动,或者输入通道被关闭时
QProcess::ReadError              4        从进程中读取数据时出错.如进程尚未启动时
QProcess::UnknownError       5        未知错误.这也是error()函数返回的默认值。

waitForStarted()阻塞直到进程已经启动;
waitForReadyRead()阻塞直到当前读通道上有可读的数据
waitForBytesWritten()阻塞直到一个有效负载数据已经被写入到进程
waitForFinished()阻塞直到进程已经结束

下面参考代码:

myProcess.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);
    ~MainWindow();
    
private slots:
    void on_pushButton_clicked();

private:
    Ui::MainWindow *ui;
    QProcess myProcess;
    QByteArray procOutput;

private slots:
    void showResult();
    void showState(QProcess::ProcessState);
    void showError();
    void showFinished(int,QProcess::ExitStatus);
};

#endif // MAINWINDOW_H

myProcess.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    connect(&myProcess, SIGNAL(readyRead()), this, SLOT(showResult()));
    connect(&myProcess, SIGNAL(stateChanged(QProcess::ProcessState)),
        this, SLOT(showState(QProcess::ProcessState)));
    connect(&myProcess, SIGNAL(error(QProcess::ProcessError)), this, SLOT(showError()));
    connect(&myProcess, SIGNAL(finished(int,QProcess::ExitStatus)),
        this, SLOT(showFinished(int, QProcess::ExitStatus)));

}

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

void MainWindow::on_pushButton_clicked()
{
#if 1
    QString cmd = ui->lineEdit->text();
    myProcess.start(cmd);
#else
    QString program="ls";
    QStringList arguments;
    arguments << "/home/linux/python";

    myProcess.start(program,arguments);
    //myProcess.startDetached() /* 启动外部程序不随主程序的退出而退出 */
#endif
    // 等待进程启动
    if (!myProcess.waitForStarted())
    {
        qDebug() << "启动失败\n";
        return;
    }
    myProcess.closeWriteChannel();


}

void MainWindow::showResult()
{
    //qDebug() << "shiwResult:" << endl << QString(myProcess.readAll());
    procOutput = myProcess.readAll();
    ui->textBrowser->setText(procOutput);
}

void MainWindow::showState(QProcess::ProcessState state)
{
    qDebug() << "showState:";

    if(state==QProcess::NotRunning){
        qDebug() << "Not Running";
    }else if(state==QProcess::Starting){
        qDebug() << "Starting";;
    }else{
        qDebug() << "Running";
    }
}

void MainWindow::showError()
{
    qDebug() << "showError:" << endl <<myProcess.errorString();
}

void MainWindow::showFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
    qDebug() << "showFinished:" << endl << exitCode << exitStatus;
    //procOutput = myProcess.readAll(); /* 读取标准输出数据 */
   // qDebug() << procOutput << endl;
}

上面代码中我注释了很多语句,那是做测试用的,仅供参考使用.


运行效果如下:



                                                                                                                 文章出自:Linux_Google


已标记关键词 清除标记
如题。 可执行的独立程序如下,是用C语言实现的哲学家就餐问题 ``` #include<stdio.h> #include<stdlib.h> #include<pthread.h> #include<unistd.h> #include<semaphore.h> #define N 3 #define LEFT i #define RIGHT (i+1)%N sem_t mutex[N]; int id[N]={0,1,2}; pthread_t thread[N]; void* solve(void*param){ int i=*((int*)param); while(i>=0){ if(i%2==0){ sem_wait(&mutex[LEFT]); sem_wait(&mutex[RIGHT]); printf("phlio %d is eating\n",i); sleep(1); sem_post(&mutex[RIGHT]); sem_post(&mutex[LEFT]); printf("phlio %d is over\n",i); sleep(1); }else{ sem_wait(&mutex[RIGHT]); sem_wait(&mutex[LEFT]); printf("phlio %d is eating\n",i); sleep(1); sem_post(&mutex[LEFT]); sem_post(&mutex[RIGHT]); printf("phlio %d is over\n",i); sleep(1); } } } int main(){ int i=0; for(i=0; i<N; i++){ sem_init(&mutex[i],0,1); pthread_create(&thread[i],NULL,solve,&id[i]); } for(i=0; i<N; i++){ pthread_join(thread[i],NULL); } return 0; } ``` Qt中使用按钮启动外部C程序,已经尝试过的方法如下(4种方法): ``` //第一种方法: void Dialog::on_pushButton_clicked() { QStringList strList; strList <<"null"<<"null"; QProcess::startDetached("/home/alison/ph1/a.out",strList,"/home/alison/ph1"); } //第二种方法: void MainWindow::on_pushButton_clicked() { QProcess *process=new QProcess; QStringList args; args<<"./a.out"; process->start("/home/alison/ph2/a.out",args); } //第三种方法: void MainWindow::on_pushButton_clicked() { QProcess *process=new QProcess; QStringList str; str <<""; process->start("/home/alison/ph2/a.out"); } //第四种方法: void MainWindow::on_pushButton_clicked() { QProcess *process=new QProcess; QProcess::execute("/home/alison/ph2/a.out"); } ``` Qt程序编译没有错误,但运行之后点击按钮没有相应的C程序运行的结果 希望各位大佬可以帮我解答一下哪里需要修改,十分感谢!
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页