進程是操做系統的基礎之一。一個進程能夠認爲是一個正在執行的程序。咱們能夠把進程當作計算機運行時的一個基礎單位。關於進程的討論已經超出了本章的範疇,如今咱們假定你是瞭解這個概念的。數組
在 Qt 中,咱們使用QProcess
來表示一個進程。這個類能夠容許咱們的應用程序開啓一個新的外部程序,而且與這個程序進行通信。下面咱們用一個很是簡單的例子開始咱們本章有關進程的闡述。網絡
//!!! Qt5 QString program = "C:/Windows/System32/cmd.exe"; QStringList arguments; arguments << "/c" << "dir" << "C:\\"; QProcess *cmdProcess = new QProcess; QObject::connect(cmdProcess, &QProcess::readyRead, [=] () { QTextCodec *codec = QTextCodec::codecForName("GBK"); QString dir = codec->toUnicode(cmdProcess->readAll()); qDebug() << dir; }); cmdProcess->start(program, arguments);
這是一段 Qt5 的程序,而且僅能運行於 Windows 平臺。簡單來講,這段程序經過 Qt 開啓了一個新的進程,這個進程至關於執行了下面的命令:異步
C:\Windows\System32\cmd.exe /c dir C:\
注意,咱們能夠在上面的程序中找到這個命令的每個字符。事實上,咱們能夠把一個進程看作執行了一段命令(在 Windows 平臺就是控制檯命令;在 Linux 平臺(包括 Unix)則是執行一個普通的命令,好比 ls)。咱們的程序至關於執行了 dir 命令,其參數是 C:\,這是由arguments
數組決定的(至於爲何咱們須要將 dir 命令做爲參數傳遞給 cmd.exe,這是因爲 Windows 平臺的規定。在 Windows 中,dir 命令並非一個獨立的可執行程序,而是經過 cmd.exe 進行解釋;這與 ls 在 Linux 中的地位不一樣,在 Linux 中,ls 就是一個可執行程序。所以若是你須要在 Linux 中執行 ls,那麼program
的值應該就是 ls )。函數
上面程序的運行結果相似於:測試
驅動器 C 中的卷是 SYSTEM 卷的序列號是 EA62-24AB C:\ 的目錄 2013/05/05 20:41 1,024 .rnd 2013/08/22 23:22 <DIR> PerfLogs 2013/10/18 07:32 <DIR> Program Files 2013/10/30 12:36 <DIR> Program Files (x86) 2013/10/31 20:30 12,906 shared.log 2013/10/18 07:33 <DIR> Users 2013/11/06 21:41 <DIR> Windows 2 個文件 13,930 字節 5 個目錄 22,723,440,640 可用字節
上面的輸出會根據不一樣機器有所不一樣。豆子是在 Windows 8.1 64位機器上測試的。編碼
爲了開啓進程,咱們將外部程序名字(program
)和程序啓動參數(arguments
)做爲參數傳給QProcess::start()
函數。固然,你也可使用setProgram()
和setArguments()
進行設置。此時,QProcess
進入Starting
狀態;當程序開始執行以後,QProcess
進入Running
狀態,而且發出started()
信號。當進程退出時,QProcess
進入NotRunning
狀態(也是初始狀態),而且發出finished()
信號。finished()
信號以參數的形式提供進程的退出代碼和退出狀態。若是發送錯誤,QProcess
會發出error()
信號操作系統
QProcess
容許你將一個進程當作一個順序訪問的 I/O 設備。咱們可使用write()
函數將數據提供給進程的標準輸入;使用read()
、readLine()
或者getChar()
函數獲取其標準輸出。因爲QProcess
繼承自QIODevice
,所以QProcess
也能夠做爲QXmlReader
的輸入或者直接使用QNetworkAccessManager
將其生成的數據上傳到網絡。線程
進程一般有兩個預約義的通道:標準輸出通道(stdout)和標準錯誤通道(stderr)。前者就是常規控制檯的輸出,後者則是由進程輸出的錯誤信息。這兩個通道都是獨立的數據流,咱們能夠經過使用setReadChannel()
函數來切換這兩個通道。當進程的當前通道可用時,QProcess
會發出readReady()
信號。當有了新的標準輸出數據時,QProcess
會發出readyReadStandardOutput()
信號;當有了新的標準錯誤數據時,則會發出readyReadStandardError()
信號。咱們前面的示例程序就是使用了readReady()
信號。注意,因爲咱們是運行在 Windows 平臺,Windows 控制檯的默認編碼是 GBK,爲了不出現亂碼,咱們必須設置文本的編碼方式。code
通道的術語可能會引發誤會。注意,進程的輸出通道對應着QProcess
的 讀 通道,進程的輸入通道對應着QProcess
的 寫 通道。這是由於咱們使用QProcess
「讀取」進程的輸出,而咱們針對QProcess
的「寫入」則成爲進程的輸入。QProcess
還能夠合併標準輸出和標準錯誤通道,使用setProcessChannelMode()
函數設置MergedChannels
便可實現。繼承
另外,QProcess
還容許咱們使用setEnvironment()
爲進程設置環境變量,或者使用setWorkingDirectory()
爲進程設置工做目錄。
前面咱們所說的信號槽機制,相似於前面咱們介紹的QNetworkAccessManager
,都是異步的。與QNetworkAccessManager
不一樣在於,QProcess
提供了同步函數:
waitForStarted()
:阻塞到進程開始;waitForReadyRead()
:阻塞到能夠從進程的當前讀通道讀取新的數據;waitForBytesWritten()
:阻塞到數據寫入進程;waitForFinished()
:阻塞到進程結束;注意,在主線程(調用了QApplication::exec()
的線程)調用上面幾個函數會讓界面失去響應。