QT开发之QProcess进程运行外部程序,在Qt中调用cmd

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()阻塞直到进程已经结束

下面参考代码:
用以下方式运行yolo后,执行检测命令,检测到的图像没有labels标记,只有框,这需要把darknet.sln源码中的image **load_alphabet() 函数中的相对地址改为.../64/data/labels/%d...绝对地址
myProcess.h
[html]  view plain  copy
  1. #ifndef MAINWINDOW_H  
  2. #define MAINWINDOW_H  
  3.   
  4. #include <QMainWindow>  
  5. #include <QProcess>  
  6.   
  7. namespace Ui {  
  8. class MainWindow;  
  9. }  
  10.   
  11. class MainWindow : public QMainWindow  
  12. {  
  13.     Q_OBJECT  
  14.       
  15. public:  
  16.     explicit MainWindow(QWidget *parent = 0);  
  17.     ~MainWindow();  
  18.       
  19. private slots:  
  20.     void on_pushButton_clicked();  
  21.   
  22. private:  
  23.     Ui::MainWindow *ui;  
  24.     QProcess myProcess;  
  25.     QByteArray procOutput;  
  26.   
  27. private slots:  
  28.     void showResult();  
  29.     void showState(QProcess::ProcessState);  
  30.     void showError();  
  31.     void showFinished(int,QProcess::ExitStatus);  
  32. };  
  33.   
  34. #endif // MAINWINDOW_H  
在界面.ui编辑器中,拖入pushbutton,lineEdit,textBrowser这三个控件,名字与代码中保持同名
myProcess.cpp
[html]  view plain  copy
  1. #include "mainwindow.h"  
  2. #include "ui_mainwindow.h"  
  3. #include <QDebug>  
  4.   
  5. MainWindow::MainWindow(QWidget *parent) :  
  6.     QMainWindow(parent),  
  7.     ui(new Ui::MainWindow)  
  8. {  
  9.     ui->setupUi(this);  
  10.     connect(&myProcess, SIGNAL(readyRead()), this, SLOT(showResult()));  
  11.     connect(&myProcess, SIGNAL(stateChanged(QProcess::ProcessState)),  
  12.         this, SLOT(showState(QProcess::ProcessState)));  
  13.     connect(&myProcess, SIGNAL(error(QProcess::ProcessError)), this, SLOT(showError()));  
  14.     connect(&myProcess, SIGNAL(finished(int,QProcess::ExitStatus)),  
  15.         this, SLOT(showFinished(int, QProcess::ExitStatus)));  
  16.   
  17. }  
  18.   
  19. MainWindow::~MainWindow()  
  20. {  
  21.     delete ui;  
  22. }  
  23.   
  24. void MainWindow::on_pushButton_clicked()  
  25. {  
  26. #if 0  
  27.     QString cmd = ui->lineEdit->text();  
  28.     myProcess.start(cmd);  
  29. #else  
  30.     QString program="cmd";  
  31.     QStringList arguments;  
  32.     arguments << "/c"<<"E:/tempFile/darknet-master/build/darknet/x64/darknet.exe detector train E:/tempFile/darknet-master/build/darknet/x64/data/obj.data E:/tempFile/darknet-master/build/darknet/x64/yolo-obj.cfg E:/tempFile/darknet-master/build/darknet/x64/darknet53.conv.74";  
  33.    //这里以深度学习网络yolov3执行训练的命令为例,另外也需要把data文件夹中的.data文件内的相对路径改为绝对路径
  34.    //myProcess.start(program,arguments); 
    //这个是在自己的textBrowser中显示输出内容
     
  35.     myProcess.startDetached(program,arguments); /* 启动外部程序不随主程序的退出而退出 */  
  36. #endif  
  37.     // 等待进程启动  
  38.     if (!myProcess.waitForStarted())  
  39.     {  
  40.         qDebug() << "启动失败\n";  
  41.         return;  
  42.     }  
  43.     myProcess.closeWriteChannel();  
  44.   
  45.   
  46. }  
  47.   
  48. void MainWindow::showResult()  
  49. {  
  50.     //qDebug() << "shiwResult:" << endl << QString(myProcess.readAll());  
  51.     procOutput = myProcess.readAll();  
  52.     ui->textBrowser->setText(procOutput);  
  53. }  
  54.   
  55. void MainWindow::showState(QProcess::ProcessState state)  
  56. {  
  57.     qDebug() << "showState:";  
  58.   
  59.     if(state==QProcess::NotRunning){  
  60.         qDebug() << "Not Running";  
  61.     }else if(state==QProcess::Starting){  
  62.         qDebug() << "Starting";;  
  63.     }else{  
  64.         qDebug() << "Running";  
  65.     }  
  66. }  
  67.   
  68. void MainWindow::showError()  
  69. {  
  70.     qDebug() << "showError:" << endl <<myProcess.errorString();  
  71. }  
  72.   
  73. void MainWindow::showFinished(int exitCode, QProcess::ExitStatus exitStatus)  
  74. {  
  75.     qDebug() << "showFinished:" << endl << exitCode << exitStatus;  
  76.     //procOutput = myProcess.readAll(); /* 读取标准输出数据 */  
  77.    // qDebug() << procOutput << endl;  
  78. }  

猜你喜欢

转载自blog.csdn.net/qq_33485434/article/details/80505471