QT计算机控制进程,Qt 学习之路 2(69):进程
進程是操作系統的基礎之一。一個進程可以認為是一個正在執行的程序。我們可以把進程當做計算機運行時的一個基礎單位。關于進程的討論已經超出了本章的范疇,現在我們假定你是了解這個概念的。
在 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
2013/10/18 07:32
2013/10/30 12:36
2013/10/31 20:30 12,906 shared.log
2013/10/18 07:33
2013/11/06 21:41
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,為了避免出現亂碼,我們必須設置文本的編碼方式。
通道的術語可能會引起誤會。注意,進程的輸出通道對應著QProcess的 讀 通道,進程的輸入通道對應著QProcess的 寫 通道。這是因為我們使用QProcess“讀取”進程的輸出,而我們針對QProcess的“寫入”則成為進程的輸入。QProcess還可以合并標準輸出和標準錯誤通道,使用setProcessChannelMode()函數設置MergedChannels即可實現。
另外,QProcess還允許我們使用setEnvironment()為進程設置環境變量,或者使用setWorkingDirectory()為進程設置工作目錄。
前面我們所說的信號槽機制,類似于前面我們介紹的QNetworkAccessManager,都是異步的。與QNetworkAccessManager不同在于,QProcess提供了同步函數:
waitForStarted():阻塞到進程開始;
waitForReadyRead():阻塞到可以從進程的當前讀通道讀取新的數據;
waitForBytesWritten():阻塞到數據寫入進程;
waitForFinished():阻塞到進程結束;
注意,在主線程(調用了QApplication::exec()的線程)調用上面幾個函數會讓界面失去響應。
總結
以上是生活随笔為你收集整理的QT计算机控制进程,Qt 学习之路 2(69):进程的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 为什么不用量子计算机挖比特币,Piete
- 下一篇: c++基础day03