QProcess快速實現外部程序調用
https://zhuanlan.zhihu.com/p/110544668
1.QProcess類及接口介紹
QProcess類是Qt中專門用於啟動一個外部程序進程並與主程序通信的。此類中包含多個靜態函數和信號,可以方便地通過信號與槽機制實現信息互通。
我們要實現快速調用外部程序,常用的有三個接口函數:
QProcess::execute()
: 此函數是以阻塞的方式打開外部程序,只有外部程序執行完成后,主程序才會繼續執行。外部程序的標准輸出、標准錯誤都是重定向到主程序的標准輸出和標准錯誤的。QProcess::start()
: 此函數是以子進程的 方式打開外部程序的,外部進程與主程序互不干擾,但外部進程的父進程就是主程序。QProcess::startDetached()
: 此函數是以分離的方式打開外部程序的,外部程序與主程序互不干擾,外部進程的父進程是系統的init
進程。
上面三個接口函數中,execute()
和startDetached()
為靜態成員函數,start()
函數為普通成員函數。 另外,值得注意的是,使用start()
函數打開外部進程時,外部進程啟動后,將隨主程序的退出而退出,使用回調即可以正常接收信息;使用startDetached()
函數打開外部進程時,外部進程啟動后,不會隨主程序的退出而退出,使用回調無法正常接收到信息。
2. 打開外部程序的應用示例
對於日常工作中,想在某項工作執行完成后,執行關機操作。這就可以使用主程序調用操作系統中的Shutdown.exe
進程。 這里先介紹一下Shutdown.exe
相關的操作指令參數,在系統命令行
中可以直接運行此進程並查看相關參數。
例如,我們要執行一小時后關機命令,可以寫如下代碼:
QStringList list; list<< "-t" << "-s" << "3600"; QProcess::startDetached("Shutdown.exe",list); // QProcess::execute("Shutdown.exe",list);
我們可以創建QProcess對象,使用start()
函數,查看外部進程返回的數據,輸出結果。其代碼可以寫成如下形式:
QProcess *pProces = new QProcess(this); connect(pProces, SIGNAL(readyRead()),this, SLOT(on_read())); QStringList list; pProces->start("Shutdown.exe", list); void on_read() { QProcess *pProces = (QProcess *)sender(); QString result = pProces->readAll(); QMessageBox::warning(NULL, "", result); }
也可以單獨執行程序,如route
、ipconfig
等。
QProcess p(0); p.start("route"); p.waitForStarted(); p.waitForFinished(); qDebug()<<QString::fromLocal8Bit(p.readAllStandardError()); QProcess p(0); p.start("ipconfig"); p.waitForStarted(); p.waitForFinished(); qDebug()<<QString::fromLocal8Bit(p.readAllStandardOutput());
也可以借助write()
函數向外部進程中寫入相應的參數,示例如下:
QProcess p(0); p.start("cmd"); p.waitForStarted(); p.write("dir\n"); p.closeWriteChannel(); p.waitForFinished(); qDebug()<<QString::fromLocal8Bit(p.readAllStandardOutput()); //或者是這一種形式 QProcess p(0); p.start("cmd", QStringList()<<"/c"<<"dir"); p.waitForStarted(); p.waitForFinished(); qDebug()<<QString::fromLocal8Bit(p.readAllStandardOutput());
我們也可以通過QProcess使用管道的功能,即一個進程的標准輸出流到目標進程的標准輸入流:command1 | command2
。其代碼如下示例:
QProcess process1; QProcess process2; process1.setStandardOutputProcess(&process2); //注意設置 process1.start("command1"); process2.start("command2");
在項目開發過程中,要根據需求場景靈活選擇適宜的接口函數,以達到滿意的效果。
==================== End