目录
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_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
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_WIN
editor = "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/
等挂载点; - 有些嵌入式系统文件系统是只读的,注意写权限;