目錄
- QT 多進程
- 復習 Linux-C 多進程
- QProcess 進程類
- 常用方法
- 簡單示例
- 信號與槽
- 應用場景
- 跨平臺注意事項
- 技巧:使用宏控制平臺命令
- QProcess 在嵌入式系統中的使用
- 示例:調用 ALSA 播放音頻
- 示例:調用 arecord 錄音
- 示例:QProcess + Shell 腳本控制外設
- 文件路徑和權限注意事項
QT 多進程
復習 Linux-C 多進程
#include <sys/types.h>
#include <unistd.h> //1.創建一個子進程 pid_t pid = fork();if(pid == 0) //子進程 {//加載程序文件system("mplayer 1.avi");}//2.創建一個子進程 pid_t pid = fork();if(pid == 0) //子進程 {//加載程序文件FILE *fp=popen("mplayer 1.avi","r+"); }
QProcess 進程類
Qt 提供 QProcess
作為 多進程管理 的主要類,用于 啟動、監控、通信 和 管理外部進程。
QProcess的啟動方式類似于Linux的
fork
+exec
。但Qt 不直接支持fork()
+exec()
創建子進程,而是推薦使用QProcess
來 跨平臺管理進程。
常用方法
構造函數
//創建一個 未啟動 的 QProcess 對象。
//需要調用 start() 或 startDetached() 啟動進程。
QProcess();
//指定父對象,用于 Qt 資源管理(自動回收)。
//適用于 QWidget 界面程序,不需要手動 delete。
QProcess(QObject parent);
方法 | 作用 | 示例 |
---|---|---|
start(program, args) | 啟動進程(可傳參數) | process->start("ping", QStringList() << "www.baidu.com"); |
startDetached(program, args) | 后臺運行進程 | QProcess::startDetached("notepad.exe"); |
kill() | 強制終止進程 | process->kill(); |
terminate() | 請求終止進程 | process->terminate(); |
waitForFinished(msecs) | 等待進程結束 | process->waitForFinished(5000); |
readAllStandardOutput() | 讀取標準輸出(一次性讀完全部) | QString output = process->readAllStandardOutput(); |
read(qint64 maxSize) | 分塊讀取(同步讀取) | QByteArray output = process.read(100); |
readAllStandardError() | 讀取標準錯誤 | QString error = process->readAllStandardError(); |
write(data) | 向進程寫入數據 | process->write("hello\n"); |
setWorkingDirectory(dir) | 設置進程工作目錄 | process->setWorkingDirectory("/home/user"); |
state() | 獲取進程狀態 | if (process->state() == QProcess::Running) { ... } |
QT 的進程的狀態枚舉值主要有三種
狀態 | 枚舉值 | 描述 |
---|---|---|
NotRunning | QProcess::NotRunning | 進程未運行(未啟動或已退出) |
Starting | QProcess::Starting | 進程正在啟動 |
Running | QProcess::Running | 進程正在運行 |
簡單示例
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include <QProcess>
QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();private slots:void on_pushButton_clicked();void on_pushButton_2_clicked();private:Ui::MainWindow *ui;QProcess *process;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{ui->setupUi(this);//創建一個未啟動的進程對象process = new QProcess(this);
}MainWindow::~MainWindow()
{delete ui;
}//啟動window記事本
void MainWindow::on_pushButton_clicked()
{process->start("notepad.exe");//啟動記事本
}//關閉window記事本
void MainWindow::on_pushButton_2_clicked()
{process->kill();//強制終止線程process->waitForFinished();//等待進程結束qDebug() << "進程已停止";
}
? 適用場景:
- 啟動本地應用(如瀏覽器、文本編輯器、終端等)。
- 調用系統命令(如
ping
、ls
、dir
)。
信號與槽
信號 | 作用 | 示例 |
---|---|---|
started() | 進程啟動后觸發 | connect(process, &QProcess::started, this, &MyClass::onStarted); |
finished(int exitCode, QProcess::ExitStatus status) | 進程結束后觸發 | connect(process, &QProcess::finished, this, &MyClass::onFinished); |
errorOccurred(QProcess::ProcessError error) | 進程錯誤 | connect(process, &QProcess::errorOccurred, this, &MyClass::onError); |
readyReadStandardOutput() | 標準輸出可讀 | connect(process, &QProcess::readyReadStandardOutput, this, &MyClass::onReadOutput); |
應用場景
【1】 遠程服務器管理
場景:使用 Qt 應用遠程 SSH 連接服務器,并執行命令。
QProcess *ssh = new QProcess(this);
ssh->start("ssh user@192.168.1.1");
ssh->write("ls -l\n");
<【2】調用 FFmpeg 進行視頻處理
場景:通過
QProcess
運行FFmpeg
命令行工具來處理視頻文件。
QProcess *ffmpeg = new QProcess(this);
ffmpeg->start("ffmpeg", QStringList() << "-i" << "input.mp4" << "-vf" << "scale=1280:720" << "output.mp4");
【3】 Qt + Python 交互
場景:Qt 作為 GUI 前端,通過
QProcess
調用 Python 處理數據。
QProcess *pyProcess = new QProcess(this);
pyProcess->start("python", QStringList() << "script.py" << "arg1" << "arg2");
跨平臺注意事項
Qt 本身是一套跨平臺框架,可以在 Windows、Linux、macOS 等系統上編寫一次、編譯多平臺運行。但當你使用 QProcess
調用系統命令或外部程序時,這部分就和平臺密切相關了。
不同操作系統的終端命令不一樣,路徑也不一樣:
操作系統 | 命令風格 | 常見路徑 | 文件后綴 |
---|---|---|---|
Windows | cmd.exe / PowerShell | C:\Windows\System32 | .exe |
Linux | Bash / Shell | /bin , /usr/bin | 無 |
macOS | Bash / Zsh | /usr/bin , /opt/homebrew/bin | 無 |
為了提高跨平臺的兼容性,此時我們可以使用 QT 提供的宏平臺控制
技巧:使用宏控制平臺命令
Qt 提供了一組宏判斷編譯平臺,你可以這樣使用:
#ifdef Q_OS_WIN
// Windows 平臺命令
#elif defined(Q_OS_LINUX)
// Linux 平臺命令
#elif defined(Q_OS_MAC)
// macOS 平臺命令
#endif
完整示例:
QString editor;
#ifdef Q_OS_WINeditor = "notepad.exe";
#elif defined(Q_OS_LINUX)editor = "gedit";
#elif defined(Q_OS_MAC)editor = "open -a TextEdit";
#endif
process->start(editor);
QProcess 在嵌入式系統中的使用
在嵌入式 Linux 系統中(如 ARM 開發板、樹莓派、瑞芯微、全志平臺等),QProcess 是非常常用的外部控制手段,可用于:
- 控制底層音視頻工具(如
aplay
,ffmpeg
,arecord
) - 啟動或關閉外部服務(如
hostapd
,wpa_supplicant
) - 調用系統命令(如
ifconfig
,iwconfig
,gpio
,i2c-tools
等) - 啟動 Python 腳本、shell 腳本等處理程序
示例:調用 ALSA 播放音頻
你可以用 QProcess
啟動 aplay
播放一個音頻文件(WAV 格式):
QProcess *process = new QProcess(this);
process->start("aplay", QStringList() << "/mnt/data/audio/test.wav");
??注意事項:
- 要保證
aplay
可執行文件存在并可執行 - 音頻文件路徑要使用開發板可讀路徑
- 音頻設備需正確配置(使用
aplay -L
可查看)
示例:調用 arecord 錄音
QProcess *record = new QProcess(this);
record->start("arecord", QStringList() << "-d" << "5" << "-f" << "cd" << "/tmp/test.wav");
含義說明:
-d 5
:錄 5 秒-f cd
:采樣格式為 CD(16bit,44100Hz)/tmp/test.wav
:輸出文件路徑
示例:QProcess + Shell 腳本控制外設
有些 GPIO 控制、WIFI 開關等操作直接寫 shell 腳本,然后用 QProcess 調用:
QProcess *gpio = new QProcess(this);
gpio->start("/home/root/scripts/led_on.sh");
如果需要 sudo:
gpio->start("sh", QStringList() << "-c" << "echo 1 > /sys/class/gpio/gpio17/value");
文件路徑和權限注意事項
- 嵌入式系統通常運行在 root 用戶下,路徑以
/
開頭; - 推薦音頻文件放置在
/home/root/
,/mnt/
或/data/
等掛載點; - 有些嵌入式系統文件系統是只讀的,注意寫權限;