【QT】 进程

发布于:2025-04-12 ⋅ 阅读:(21) ⋅ 点赞:(0)

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() << "进程已停止";
}

在这里插入图片描述

适用场景

  • 启动本地应用(如浏览器、文本编辑器、终端等)。
  • 调用系统命令(如 pinglsdir)。

信号与槽

信号 作用 示例
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/ 等挂载点;
  • 有些嵌入式系统文件系统是只读的,注意写权限;

网站公告

今日签到

点亮在社区的每一天
去签到