Qt 是一個跨平臺C++圖形界面開發庫,利用Qt可以快速開發跨平臺窗體應用程式,在Qt中我們可以通過拖拽的方式將不同組件放到指定的位置,實現圖形化開發極大的方便了開發效率,本章將重點介紹如何運用`QProcess`組件實現針對進程的控制管理等。當你在使用Qt進行跨平臺應用程式開發時,經常需要與外部進... ...
Qt 是一個跨平臺C++圖形界面開發庫,利用Qt可以快速開發跨平臺窗體應用程式,在Qt中我們可以通過拖拽的方式將不同組件放到指定的位置,實現圖形化開發極大的方便了開發效率,本章將重點介紹如何運用QProcess
組件實現針對進程的控制管理等。
當你在使用Qt進行跨平臺應用程式開發時,經常需要與外部進程進行交互,這時就可以利用Qt的QProcess
模塊。QProcess
模塊提供了啟動和控制外部進程的功能,能夠執行外部命令、運行其他可執行文件,以及與外部進程進行通信。通過QProcess
,可以方便地執行命令行命令、調用系統工具、執行腳本等。QProcess
還可以捕獲外部進程的輸出,以及監視外部進程的運行狀態,從而實現更靈活、高效的進程管理。
以下是QProcess
類的一些常用函數及其解釋的表格:
函數 | 描述 |
---|---|
start(const QString &program, const QStringList &arguments) |
啟動一個新的進程,program 參數指定要執行的程式,arguments 參數指定傳遞給程式的參數列表。 |
startDetached(const QString &program, const QStringList &arguments) |
啟動一個新的進程,但不會等待進程退出,也不會將輸出傳遞給調用進程。 |
waitForStarted(int msecs = 30000) |
等待進程啟動,如果在指定時間內進程沒有啟動,將返回false。 |
waitForFinished(int msecs = 30000) |
等待進程退出,如果在指定時間內進程沒有退出,將返回false。 |
readAllStandardOutput() |
讀取進程的標準輸出,並返回為QByteArray 。 |
readAllStandardError() |
讀取進程的標準錯誤輸出,並返回為QByteArray 。 |
write(const QByteArray &data) |
向進程的標準輸入寫入數據。 |
closeWriteChannel() |
關閉進程的標準輸入。 |
kill() |
終止進程。 |
terminate() |
終止進程。 |
start(const QString &program) |
啟動一個新的進程,program 參數指定要執行的程式。 |
setWorkingDirectory(const QString &dir) |
設置進程的工作目錄。 |
state() |
返回進程的當前狀態。 |
error() |
返回進程的錯誤狀態。 |
pid() |
返回進程的進程ID。 |
waitForBytesWritten(int msecs = 30000) |
等待寫入到進程的數據已經被完全寫入。 |
waitForReadyRead(int msecs = 30000) |
等待進程有數據可讀。 |
startDetached(const QString &program) |
啟動一個新的進程,但不會等待進程退出,也不會將輸出傳遞給調用進程。 |
setProcessChannelMode(QProcess::ProcessChannelMode mode) |
設置進程通信模式,可選值包括QProcess::SeparateChannels 和QProcess::MergedChannels 。 |
這些函數提供了控制進程的各種方法,可以實現啟動、監視、控制和與外部進程進行交互的功能。
進程式控制制模塊可以實現對特定進程的啟動關閉,本章將以執行命令行為例,通過調用Start()
可以拉起一個第三方進程。
QProcess
類的start()
函數有幾種不同的重載形式,但最常用的是以下形式:
bool QProcess::start(
const QString &program,
const QStringList &arguments,
QIODevice::OpenMode mode = ReadWrite
)
函數用於啟動一個新的進程,並執行指定的程式(program
參數)。arguments
參數指定了傳遞給程式的參數列表,它是一個QStringList
類型的參數,可以為空。mode
參數指定了啟動進程時打開的模式,預設為ReadWrite
。函數返回一個bool
類型的值,表示進程是否成功啟動。
當調用start()
執行命令後,我們則可以通過readAllStandardOutput()
函數從進程的標準輸出中讀取所有可用的數據,並將其返回為 QByteArray
對象。
QByteArray QProcess::readAllStandardOutput()
這個函數沒有參數,它會立即返回當前可用的標準輸出數據,並將輸出數據作為位元組數組返回。如果沒有可用的輸出數據,它將返回一個空的位元組數組。
當然了,與之對應的readAllStandardError()
是函數,該函數可以用於從進程的標準錯誤輸出中讀取所有可用的數據,並將其返回為 QByteArray
對象。
QByteArray QProcess::readAllStandardError()
該函數同樣沒有參數,它會立即返回當前可用的標準錯誤輸出數據,並將輸出數據作為位元組數組返回。如果沒有可用的錯誤輸出數據,它將返回一個空的位元組數組。
1.1 獲取進程信息
此處我們以輸出系統進程信息為例,通常可以調用tasklist /FO CSV
來獲取系統中的進程列表,並將其輸出為CSV
格式,通過調用如下函數則可以獲取到系統進程信息。
process.start("tasklist", QStringList() << "/FO" << "CSV");
此時通過調用readAllStandardOutput
函數我們可以將緩衝區內的數據讀出並將其放入到一個QString
類型變數內;
QString output = process.readAllStandardOutput();
當具備了這個列表後,就可以根據冒號來逐行讀入並切割,通過迴圈的方式將其追加到treeWidget
組件內,並以此來實現展示的效果;
void MainWindow::on_pushButton_clicked()
{
CallProcess();
ui->treeWidget->clear();
QProcess process;
process.start("tasklist", QStringList() << "/FO" << "CSV");
if (process.waitForFinished())
{
QString output = process.readAllStandardOutput();
output.replace("\"", "");
QStringList lines = output.split("\n");
// 跳過第一行標題
for(int i = 1; i < lines.size(); ++i)
{
QStringList fields = lines[i].split(",");
// 確保至少有五個欄位
if(fields.size() >= 5)
{
QStringList rowData;
for(int j = 0; j < 5; ++j)
{
rowData << fields[j].trimmed();
}
ui->treeWidget->addTopLevelItem(new QTreeWidgetItem(rowData));
}
}
// 設置列標題
ui->treeWidget->setHeaderLabels(QStringList() << "進程名稱" << "PID" << "會話名稱" << "Session"<< "記憶體占用");
} else
{
QTreeWidgetItem *item = new QTreeWidgetItem(ui->treeWidget);
item->setText(0, "Failed to execute tasklist command.");
}
}
運行後當點擊輸出系統進程時則可以看到完整的進程輸出效果,如下圖所示;
使用此方法我們可以很好的讀取到系統中的各種信息,只要能夠合理的過濾出想要的欄位即可,當需要輸出系統信息時我們可以通過process.start("systeminfo")
調用系統命令獲取到,如下代碼所示;
void MainWindow::on_pushButton_2_clicked()
{
ui->treeWidget->clear();
// 獲取系統信息
QProcess process;
process.start("systeminfo");
if (process.waitForFinished())
{
QByteArray output = process.readAllStandardOutput();
// 使用正確的文本編碼對輸出進行解碼
QTextCodec *codec = QTextCodec::codecForName("GBK");
QString text = codec->toUnicode(output);
QStringList lines = text.split("\n");
for (const QString &line : lines)
{
// 解析系統信息,添加到 QTreeWidget 中
QStringList fields = line.split(":", Qt::SkipEmptyParts);
if (fields.size() >= 2)
{
QString property = fields[0].trimmed();
QString value = fields[1].trimmed();
QTreeWidgetItem *item = new QTreeWidgetItem(ui->treeWidget);
item->setText(0, property);
item->setText(1, value);
}
}
// 設置列標題
ui->treeWidget->setHeaderLabels(QStringList() << "系統信息" << "數值");
} else
{
QTreeWidgetItem *item = new QTreeWidgetItem(ui->treeWidget);
item->setText(0, "Failed to execute systeminfo command.");
}
}
運行後當用戶點擊輸出系統信息按鈕時,因systeminfo
運行時間較長所以需要等待一段時間,輸出效果如下圖所示;
本博客所有文章除特別聲明外,均採用 BY-NC-SA 許可協議。轉載請註明出處!