QT计算机控制进程,Qt 学习之路 2(69):进程
進(jìn)程是操作系統(tǒng)的基礎(chǔ)之一。一個(gè)進(jìn)程可以認(rèn)為是一個(gè)正在執(zhí)行的程序。我們可以把進(jìn)程當(dāng)做計(jì)算機(jī)運(yùn)行時(shí)的一個(gè)基礎(chǔ)單位。關(guān)于進(jìn)程的討論已經(jīng)超出了本章的范疇,現(xiàn)在我們假定你是了解這個(gè)概念的。
在 Qt?中,我們使用QProcess來(lái)表示一個(gè)進(jìn)程。這個(gè)類可以允許我們的應(yīng)用程序開啟一個(gè)新的外部程序,并且與這個(gè)程序進(jìn)行通訊。下面我們用一個(gè)非常簡(jiǎn)單的例子開始我們本章有關(guān)進(jìn)程的闡述。
//!!! 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 的程序,并且僅能運(yùn)行于 Windows 平臺(tái)。簡(jiǎn)單來(lái)說(shuō),這段程序通過(guò) Qt 開啟了一個(gè)新的進(jìn)程,這個(gè)進(jìn)程相當(dāng)于執(zhí)行了下面的命令:
C:\\Windows\\System32\\cmd.exe /c dir C:\\
注意,我們可以在上面的程序中找到這個(gè)命令的每一個(gè)字符。事實(shí)上,我們可以把一個(gè)進(jìn)程看做執(zhí)行了一段命令(在 Windows 平臺(tái)就是控制臺(tái)命令;在 Linux 平臺(tái)(包括 Unix)則是執(zhí)行一個(gè)普通的命令,比如 ls)。我們的程序相當(dāng)于執(zhí)行了 dir 命令,其參數(shù)是 C:\,這是由arguments數(shù)組決定的(至于為什么我們需要將 dir 命令作為參數(shù)傳遞給 cmd.exe,這是由于 Windows 平臺(tái)的規(guī)定。在 Windows 中,dir 命令并不是一個(gè)獨(dú)立的可執(zhí)行程序,而是通過(guò) cmd.exe 進(jìn)行解釋;這與 ls 在 Linux 中的地位不同,在 Linux 中,ls 就是一個(gè)可執(zhí)行程序。因此如果你需要在 Linux 中執(zhí)行 ls,那么program的值應(yīng)該就是 ls )。
上面程序的運(yùn)行結(jié)果類似于:
驅(qū)動(dòng)器 C 中的卷是 SYSTEM
卷的序列號(hào)是 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 個(gè)文件 13,930 字節(jié)
5 個(gè)目錄 22,723,440,640 可用字節(jié)
上面的輸出會(huì)根據(jù)不同機(jī)器有所不同。豆子是在 Windows 8.1 64位機(jī)器上測(cè)試的。
為了開啟進(jìn)程,我們將外部程序名字(program)和程序啟動(dòng)參數(shù)(arguments)作為參數(shù)傳給QProcess::start()函數(shù)。當(dāng)然,你也可以使用setProgram()和setArguments()進(jìn)行設(shè)置。此時(shí),QProcess進(jìn)入Starting?狀態(tài);當(dāng)程序開始執(zhí)行之后,QProcess進(jìn)入Running?狀態(tài),并且發(fā)出started()信號(hào)。當(dāng)進(jìn)程退出時(shí),QProcess進(jìn)入NotRunning狀態(tài)(也是初始狀態(tài)),并且發(fā)出finished()信號(hào)。finished()信號(hào)以參數(shù)的形式提供進(jìn)程的退出代碼和退出狀態(tài)。如果發(fā)送錯(cuò)誤,QProcess會(huì)發(fā)出error()信號(hào)
QProcess允許你將一個(gè)進(jìn)程當(dāng)做一個(gè)順序訪問(wèn)的 I/O 設(shè)備。我們可以使用write()函數(shù)將數(shù)據(jù)提供給進(jìn)程的標(biāo)準(zhǔn)輸入;使用read()、readLine()或者getChar()函數(shù)獲取其標(biāo)準(zhǔn)輸出。由于QProcess繼承自QIODevice,因此QProcess也可以作為QXmlReader的輸入或者直接使用QNetworkAccessManager將其生成的數(shù)據(jù)上傳到網(wǎng)絡(luò)。
進(jìn)程通常有兩個(gè)預(yù)定義的通道:標(biāo)準(zhǔn)輸出通道(stdout)和標(biāo)準(zhǔn)錯(cuò)誤通道(stderr)。前者就是常規(guī)控制臺(tái)的輸出,后者則是由進(jìn)程輸出的錯(cuò)誤信息。這兩個(gè)通道都是獨(dú)立的數(shù)據(jù)流,我們可以通過(guò)使用setReadChannel()函數(shù)來(lái)切換這兩個(gè)通道。當(dāng)進(jìn)程的當(dāng)前通道可用時(shí),QProcess會(huì)發(fā)出readReady()信號(hào)。當(dāng)有了新的標(biāo)準(zhǔn)輸出數(shù)據(jù)時(shí),QProcess會(huì)發(fā)出readyReadStandardOutput()信號(hào);當(dāng)有了新的標(biāo)準(zhǔn)錯(cuò)誤數(shù)據(jù)時(shí),則會(huì)發(fā)出readyReadStandardError()信號(hào)。我們前面的示例程序就是使用了readReady()信號(hào)。注意,由于我們是運(yùn)行在 Windows 平臺(tái),Windows 控制臺(tái)的默認(rèn)編碼是 GBK,為了避免出現(xiàn)亂碼,我們必須設(shè)置文本的編碼方式。
通道的術(shù)語(yǔ)可能會(huì)引起誤會(huì)。注意,進(jìn)程的輸出通道對(duì)應(yīng)著QProcess的 讀 通道,進(jìn)程的輸入通道對(duì)應(yīng)著QProcess的 寫 通道。這是因?yàn)槲覀兪褂肣Process“讀取”進(jìn)程的輸出,而我們針對(duì)QProcess的“寫入”則成為進(jìn)程的輸入。QProcess還可以合并標(biāo)準(zhǔn)輸出和標(biāo)準(zhǔn)錯(cuò)誤通道,使用setProcessChannelMode()函數(shù)設(shè)置MergedChannels即可實(shí)現(xiàn)。
另外,QProcess還允許我們使用setEnvironment()為進(jìn)程設(shè)置環(huán)境變量,或者使用setWorkingDirectory()為進(jìn)程設(shè)置工作目錄。
前面我們所說(shuō)的信號(hào)槽機(jī)制,類似于前面我們介紹的QNetworkAccessManager,都是異步的。與QNetworkAccessManager不同在于,QProcess提供了同步函數(shù):
waitForStarted():阻塞到進(jìn)程開始;
waitForReadyRead():阻塞到可以從進(jìn)程的當(dāng)前讀通道讀取新的數(shù)據(jù);
waitForBytesWritten():阻塞到數(shù)據(jù)寫入進(jìn)程;
waitForFinished():阻塞到進(jìn)程結(jié)束;
注意,在主線程(調(diào)用了QApplication::exec()的線程)調(diào)用上面幾個(gè)函數(shù)會(huì)讓界面失去響應(yīng)。
總結(jié)
以上是生活随笔為你收集整理的QT计算机控制进程,Qt 学习之路 2(69):进程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 为什么不用量子计算机挖比特币,Piete
- 下一篇: c++基础day03