QProcess
可用於完成啟動外部程序,並與之交互通信。
一、啟動外部程序的兩種方式
1)一體式:void QProcess::start(const QString & program,const QStringList &arguments,OpenMode mode = ReadWrite)
外部程序啟動后,將隨主程序的退出而退出。
2)分離式:void QProcess::startDetached(const QString & program,const QStringList & arguments,const QString&workingDirectory=QString(),qint64 *pid =0)
外部程序啟動后,當主程序退出時並不退出,而是繼續運行。
二、啟動之前需要做的工作:
啟動一個外部程序,需要傳遞外部程序的路徑和執行參數,參數用QStringList來帶入。
1)設置路徑
void QProcess::setProgram(const QString & program)
2)設置參數【可選】
void QProcess::setArguments(const QStringList & arguments)
3)啟動
選擇啟動函數(兩種方式)
三、啟動狀態
外部程序未啟動時,其狀態是NotRunning;
當啟動時,其狀態轉變為Starting,正在啟動,但此時還未調用起來;
啟動之后,繼續變為Running,同時發射出started()信號,此時,可以對QProcess進行讀寫操作了;
當退出時,其狀態改為NotRunning,並發射出finished()信號。finished()信號會攜帶退出碼和退出狀態,可以分別通過exitCode()和exitStatus()來獲得。
當發生錯誤時,QProcess會發出一個error()信號,同樣的,也可以通過error()來獲得其錯誤類型,通過state()獲得當前程序的狀態。
四、QProcess與QIODevice
QProcess繼承與QIODevice,因此,我們可以把它當作一個I/O設備進行讀寫操作。
五、交互
QProcess有兩種預定義的輸入通道:標准輸出stdout與標准錯誤stderr.
通過setReadChannel可以讀取輸出的通道。
當通道的數據准備就緒時,QProcess會發出readyRead()信號。如果是標准輸出,則發出readyReadStandardOutput()信號。如果是標准錯誤,
則發出readyReadStandardError()信號。
常用的讀取方式有read(),readAll()或getChar(),也可以通過readAllStandardOutput()和readAllStandardError()讀取標准輸出和標准錯誤通道中的數據。
某些程序需要設置環境才能進行特殊的操作。可以通過setEnvironment()來設置環境變量,通過setWorkingDirectory()來設置工作目錄,默認的工作路徑是當前調用程序的工作路徑。
六、同步API
QProcess提供了一系列的函數以提到事件循環來完成同步操作:
1)waitForStarted()//阻塞,直到外部程序啟動
2)waitForReadyRead()//阻塞,直到輸出通道中的新數據可讀
3) waitForBytesWritten()//阻塞,直到輸入通道中的數據被寫入
4) waitForFinished() //阻塞,直到外部程序結束
如果在主線程中調用這些函數,可能會造成當前用戶界面不響應。
七、QProcess進程類
Qt提供了一個QProcess類用於啟動外部程序並與之通信,啟動一個新的進程的操作非常簡單,只需要將待啟動的程序名稱和啟動參數傳遞給start()函數即可。
例:
Qobject *parent;
QString program = "tar";
QStringList arguments;
arguments<<"czvf"<<"backup.tar.gz"<<"/home";
QProcess *myProcess= new QProcess(parent);
QProcess->start(program,arguments);
當調用start()函數后,myProcess進程立即進入啟動狀態,但tar程序尚未被調用,不能讀入標准輸入輸出設備。當進程完成啟動后就進入“運行狀態”並向外發送出
started()信號,在輸入輸出方面,QProcess將一個進程看做一個類型的I/O設備,可以像使用QTcpSocket讀寫流類型的網絡連接一樣來讀寫一個進程。
可以通過QIODevice::write()函數向所啟動的進程的標准輸入寫數據,也可以通過QIODeivic::read()、QIODevice::readLine()、QIODevice::getChar()函數從這個進程的標准輸出讀數據。此外由於QProcess是從QIODevice類繼承而來的。
Qt定義了如下的進程錯誤代碼:
錯誤常量 值 描述
QProcess::FailedToStart 0 進程啟動失敗
QProcess::Crashed 1 進程成功后崩潰
QProcess::Timedout 2 最后一次調用waitFor...()函數超時。此時QProcess狀態不變,並可以再次調用waitFor...()類型的函數
QProcess::WriteError 3 向進程中寫入數據時出錯。如進程尚未啟動,或者輸入通道被關閉時。
QProcee::ReadError 4 從進程中讀取數據時出錯。如進程尚未啟動時
QProcess::UnknownError 5 未知錯誤。這也是error()函數返回的默認值。
八、進程的標准輸出:
stdout:通常用於控制台下輸出
stderr:通常用於進程打印錯誤
它們本質上是兩個獨立的數據流
可以通過調用setReadChanned()函數設置當前的讀通道
當有可讀數據時Qt將發出readyRead()信號
如果是標准輸出和標准錯誤通道中讀取數據,還會發出readyReadStandardOutput()信號
readAllStandardOutput()函數從標准輸出通道中讀取數據
readAllStandardErrot()函數從標准錯誤通道中讀取數據
在進程啟動以前以MergedChannels參數調用setReadChannelMode()函數可以把標准輸出通道和標准輸出錯誤通道合並。