开源 C++ QT QML 开发(十四)进程用途

文章的目的为了记录使用QT QML开发学习的经历。开发流程和要点有些记忆模糊,赶紧记录,防止忘记。

相关链接:

开源 C++ QT QML 开发(一)基本介绍

开源 C++ QT QML 开发(二)工程结构

开源 C++ QT QML 开发(三)常用控件

开源 C++ QT QML 开发(四)复杂控件--Listview

开源 C++ QT QML 开发(五)复杂控件--Gridview

开源 C++ QT QML 开发(六)自定义控件--波形图

开源 C++ QT QML 开发(七)自定义控件--仪表盘

推荐链接:

开源 C# 快速开发(一)基础知识

开源 C# 快速开发(二)基础控件

开源 C# 快速开发(三)复杂控件

开源 C# 快速开发(四)自定义控件--波形图

开源 C# 快速开发(五)自定义控件--仪表盘

开源 C# 快速开发(六)自定义控件--圆环

开源 C# 快速开发(七)通讯--串口

开源 C# 快速开发(八)通讯--Tcp服务器端

开源 C# 快速开发(九)通讯--Tcp客户端

开源 C# 快速开发(十)通讯--http客户端

开源 C# 快速开发(十一)线程

开源 C# 快速开发(十二)进程监控

开源 C# 快速开发(十三)进程--管道通讯

开源 C# 快速开发(十四)进程--内存映射

开源 C# 快速开发(十五)进程--windows消息

开源 C# 快速开发(十六)数据库--sqlserver增删改查

本章节主要内容是:使用进程进行进程的监控,进程调用,命令的执行,演示进程的作用。

1.代码分析

2.所有源码

3.效果演示

一、代码分析

二、所有源码

三、效果演示

可以显示当前进程,打开记事本,执行dir命令,演示进程的三种功能。

  1. C++ 后台代码分析

ProcessManager 类头文件 (processmanager.h)

复制代码
class ProcessManager : public QObject
{
    Q_OBJECT  // Qt的元对象系统宏,启用信号槽机制

作用:继承自QObject,使类能够使用Qt的信号槽机制

构造函数

复制代码
explicit ProcessManager(QObject *parent = nullptr) : QObject(parent) {}

作用:简单的构造函数,调用父类QObject的构造函数

showCurrentProcess() 函数

复制代码
void showCurrentProcess()
{
    qDebug() << "当前进程PID:" << QCoreApplication::applicationPid();
    emit processInfoReady("当前进程PID: " + QString::number(QCoreApplication::applicationPid()));
}

详细分析:

QCoreApplication::applicationPid():获取当前应用程序的进程ID

qDebug():在控制台输出调试信息

emit processInfoReady():发射信号,将信息传递到QML界面

功能:显示当前Qt应用程序自身的进程ID

openNotepad() 函数

复制代码
void openNotepad()
{
    QProcess *process = new QProcess(this);  // 创建QProcess对象,this指定父对象用于自动内存管理
    
    // 连接进程结束信号到lambda表达式
    connect(process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
            [process](int exitCode, QProcess::ExitStatus exitStatus) {
        qDebug() << "记事本进程结束,退出码:" << exitCode;
        process->deleteLater();  // 安全删除进程对象
    });

#ifdef Q_OS_WIN
    process->start("notepad.exe");  // Windows系统启动记事本
#else
    process->start("gedit");  // Linux系统启动gedit
#endif
    
    if (process->waitForStarted()) {  // 等待进程启动,超时时间默认30秒
        emit processInfoReady("记事本已启动");
    } else {
        emit processInfoReady("启动记事本失败");
    }
}

详细分析:

QProcess *process = new QProcess(this):创建进程对象,指定父对象实现自动内存管理

connect(... finished ...):连接进程结束信号,使用lambda表达式处理

QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished):处理重载信号的正确连接方式

process->deleteLater():在事件循环中安全删除对象

预处理指令 #ifdef Q_OS_WIN:实现跨平台兼容

process->start():启动外部程序

process->waitForStarted():阻塞等待进程启动,返回布尔值表示是否成功

executeDirCommand() 函数

复制代码
void executeDirCommand()
{
    QProcess *process = new QProcess(this);
    
    // 连接标准输出信号
    connect(process, &QProcess::readyReadStandardOutput, [process, this]() {
        QString output = QString::fromLocal8Bit(process->readAllStandardOutput());
        emit commandOutputReady(output);
    });

    // 连接标准错误信号
    connect(process, &QProcess::readyReadStandardError, [process, this]() {
        QString error = QString::fromLocal8Bit(process->readAllStandardError());
        emit commandOutputReady("错误: " + error);
    });

    // 连接进程结束信号
    connect(process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
            [process, this](int exitCode, QProcess::ExitStatus exitStatus) {
        emit commandOutputReady("\n命令执行完成,退出码: " + QString::number(exitCode));
        process->deleteLater();
    });

#ifdef Q_OS_WIN
    process->start("cmd", QStringList() << "/c" << "dir");  // Windows执行dir命令
#else
    process->start("ls", QStringList() << "-l");  // Linux执行ls -l命令
#endif
    
    if (!process->waitForStarted()) {
        emit commandOutputReady("启动命令失败");
    }
}

详细分析:

readyReadStandardOutput:当进程有标准输出时触发

readyReadStandardError:当进程有错误输出时触发

readAllStandardOutput():读取所有标准输出数据

QString::fromLocal8Bit():将本地8位编码转换为QString

QStringList() << "/c" << "dir":创建参数列表,/c表示执行后终止cmd

使用三个独立的connect来分别处理输出、错误和结束事件

信号声明

复制代码
signals:
    void processInfoReady(const QString &info);
    void commandOutputReady(const QString &output);

作用:定义两个信号,用于C++到QML的通信

  1. main.cpp 分析

    int main(int argc, char *argv[])
    {
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); // 启用高DPI缩放
    QGuiApplication app(argc, argv); // 创建GUI应用程序对象

    复制代码
     ProcessManager processManager;  // 创建进程管理器实例
    
     QQmlApplicationEngine engine;  // 创建QML引擎
     
     // 将C++对象注册为QML上下文属性
     engine.rootContext()->setContextProperty("processManager", &processManager);
     
     // 从qrc资源文件加载QML
     engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
     
     if (engine.rootObjects().isEmpty())  // 检查QML是否加载成功
         return -1;
    
     return app.exec();  // 进入主事件循环

    }

  2. QML 界面详细分析

ApplicationWindow

复制代码
ApplicationWindow {
    id: window
    width: 800
    height: 600
    visible: true
    title: "Qt进程管理示例"

作用:创建主应用程序窗口

背景渐变

复制代码
Rectangle {
    anchors.fill: parent
    gradient: Gradient {
        GradientStop { position: 0.0; color: "#2c3e50" }
        GradientStop { position: 1.0; color: "#3498db" }
    }
}

作用:创建从深蓝色到浅蓝色的垂直渐变背景

按钮组件分析

复制代码
Button {
    Layout.fillWidth: true
    text: "显示当前进程"
    font.pixelSize: 16
    
    background: Rectangle {
        color: parent.down ? "#27ae60" : "#2ecc71"  // 按下时变深色
        radius: 8  // 圆角
    }
    contentItem: Text {
        text: parent.text
        font: parent.font
        color: "white"
        horizontalAlignment: Text.AlignHCenter
        verticalAlignment: Text.AlignVCenter
    }
    
    onClicked: {
        processManager.showCurrentProcess()  // 调用C++函数
    }
}

详细分析:

Layout.fillWidth: true:在布局中填充宽度

background:自定义按钮背景,实现按下状态颜色变化

contentItem:自定义按钮文本样式

onClicked:按钮点击事件处理器,调用C++函数

输出显示区域

复制代码
ScrollView {
    anchors.fill: parent
    anchors.margins: 5

    TextArea {
        id: outputArea
        readOnly: true  // 只读
        wrapMode: Text.Wrap  // 自动换行
        color: "#ecf0f1"  // 文字颜色
        font.pixelSize: 12
        font.family: "Courier New"  // 等宽字体,适合显示命令输出
        background: null  // 透明背景
        placeholderText: "命令输出将显示在这里..."
    }
}

Connections 组件

复制代码
Connections {
    target: processManager  // 连接的C++对象
    
    onProcessInfoReady: {  // 处理processInfoReady信号
        infoArea.text = info + "\n" + infoArea.text  // 新信息添加到顶部
    }
    
    onCommandOutputReady: {  // 处理commandOutputReady信号
        outputArea.text = output + outputArea.text
    }
}

作用:建立C++信号到QML的连接,实现数据传递

二、所有源码

processmanager .h文件源码

复制代码
#ifndef PROCESSMANAGER_H
#define PROCESSMANAGER_H

#include <QObject>
#include <QProcess>
#include <QDebug>
#include <QCoreApplication>

class ProcessManager : public QObject
{
    Q_OBJECT

public:
    explicit ProcessManager(QObject *parent = nullptr) : QObject(parent) {}

public slots:
    // 显示当前进程信息
    void showCurrentProcess()
    {
        qDebug() << "当前进程PID:" << QCoreApplication::applicationPid();
        emit processInfoReady("当前进程PID: " + QString::number(QCoreApplication::applicationPid()));
    }

    // 打开记事本
    void openNotepad()
    {
        QProcess *process = new QProcess(this);

        // 进程结束时自动删除
        connect(process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
                [process](int exitCode, QProcess::ExitStatus exitStatus) {
            qDebug() << "记事本进程结束,退出码:" << exitCode;
            process->deleteLater();
        });

#ifdef Q_OS_WIN
        process->start("notepad.exe");
#else
        process->start("gedit");  // Linux系统使用gedit
#endif

        if (process->waitForStarted()) {
            emit processInfoReady("记事本已启动");
        } else {
            emit processInfoReady("启动记事本失败");
        }
    }

    // 执行cmd dir命令
    void executeDirCommand()
    {
        QProcess *process = new QProcess(this);

        connect(process, &QProcess::readyReadStandardOutput, [process, this]() {
            QString output = QString::fromLocal8Bit(process->readAllStandardOutput());
            emit commandOutputReady(output);
        });

        connect(process, &QProcess::readyReadStandardError, [process, this]() {
            QString error = QString::fromLocal8Bit(process->readAllStandardError());
            emit commandOutputReady("错误: " + error);
        });

        connect(process, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished),
                [process, this](int exitCode, QProcess::ExitStatus exitStatus) {
            emit commandOutputReady("\n命令执行完成,退出码: " + QString::number(exitCode));
            process->deleteLater();
        });

#ifdef Q_OS_WIN
        process->start("cmd", QStringList() << "/c" << "dir");
#else
        process->start("ls", QStringList() << "-l");  // Linux系统使用ls -l
#endif

        if (!process->waitForStarted()) {
            emit commandOutputReady("启动命令失败");
        }
    }

signals:
    void processInfoReady(const QString &info);
    void commandOutputReady(const QString &output);
};

#endif // PROCESSMANAGER_H

main.qml文件源码

复制代码
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12

ApplicationWindow {
    id: window
    width: 800
    height: 600
    visible: true
    title: "Qt进程管理示例"

    // 背景渐变
    Rectangle {
        anchors.fill: parent
        gradient: Gradient {
            GradientStop { position: 0.0; color: "#2c3e50" }
            GradientStop { position: 1.0; color: "#3498db" }
        }
    }

    ColumnLayout {
        anchors.fill: parent
        anchors.margins: 20
        spacing: 15

        // 标题
        Text {
            Layout.alignment: Qt.AlignHCenter
            text: "进程管理演示"
            font.pixelSize: 28
            font.bold: true
            color: "white"
        }

        // 按钮区域
        RowLayout {
            Layout.fillWidth: true
            spacing: 15

            // 显示当前进程按钮
            Button {
                Layout.fillWidth: true
                text: "显示当前进程"
                font.pixelSize: 16

                background: Rectangle {
                    color: parent.down ? "#27ae60" : "#2ecc71"
                    radius: 8
                }
                contentItem: Text {
                    text: parent.text
                    font: parent.font
                    color: "white"
                    horizontalAlignment: Text.AlignHCenter
                    verticalAlignment: Text.AlignVCenter
                }

                onClicked: {
                    processManager.showCurrentProcess()
                }
            }

            // 打开记事本按钮
            Button {
                Layout.fillWidth: true
                text: "打开记事本"
                font.pixelSize: 16

                background: Rectangle {
                    color: parent.down ? "#2980b9" : "#3498db"
                    radius: 8
                }
                contentItem: Text {
                    text: parent.text
                    font: parent.font
                    color: "white"
                    horizontalAlignment: Text.AlignHCenter
                    verticalAlignment: Text.AlignVCenter
                }

                onClicked: {
                    processManager.openNotepad()
                }
            }

            // 执行Dir命令按钮
            Button {
                Layout.fillWidth: true
                text: "执行Dir命令"
                font.pixelSize: 16

                background: Rectangle {
                    color: parent.down ? "#c0392b" : "#e74c3c"
                    radius: 8
                }
                contentItem: Text {
                    text: parent.text
                    font: parent.font
                    color: "white"
                    horizontalAlignment: Text.AlignHCenter
                    verticalAlignment: Text.AlignVCenter
                }

                onClicked: {
                    processManager.executeDirCommand()
                    outputArea.text = "执行命令中..."
                }
            }
        }

        // 信息显示区域
        Rectangle {
            Layout.fillWidth: true
            Layout.preferredHeight: 100
            color: "#34495e"
            radius: 8
            border.color: "#7f8c8d"
            border.width: 2

            ScrollView {
                anchors.fill: parent
                anchors.margins: 5

                TextArea {
                    id: infoArea
                    readOnly: true
                    wrapMode: Text.Wrap
                    color: "#ecf0f1"
                    font.pixelSize: 14
                    background: null
                    placeholderText: "进程信息将显示在这里..."
                }
            }
        }

        // 命令输出区域
        Rectangle {
            Layout.fillWidth: true
            Layout.fillHeight: true
            color: "#2c3e50"
            radius: 8
            border.color: "#7f8c8d"
            border.width: 2

            ScrollView {
                anchors.fill: parent
                anchors.margins: 5

                TextArea {
                    id: outputArea
                    readOnly: true
                    wrapMode: Text.Wrap
                    color: "#ecf0f1"
                    font.pixelSize: 12
                    font.family: "Courier New"
                    background: null
                    placeholderText: "命令输出将显示在这里..."
                }
            }
        }

        // 状态栏
        Rectangle {
            Layout.fillWidth: true
            Layout.preferredHeight: 30
            color: "#1abc9c"
            radius: 5

            Text {
                anchors.centerIn: parent
                text: "Qt 5.12 进程管理示例 - 使用QProcess类"
                color: "white"
                font.pixelSize: 12
            }
        }
    }

    // 连接C++信号到QML
    Connections {
        target: processManager

        onProcessInfoReady: {
            infoArea.text = info + "\n" + infoArea.text
        }

        onCommandOutputReady: {
            outputArea.text = output + outputArea.text
        }
    }
}

main.cpp文件源码

复制代码
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "processmanager.h"

int main(int argc, char *argv[])
{
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);

    // 注册进程管理器到QML
    ProcessManager processManager;

    QQmlApplicationEngine engine;

    // 将C++对象暴露给QML
    engine.rootContext()->setContextProperty("processManager", &processManager);

    // 加载QML文件
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    if (engine.rootObjects().isEmpty())
        return -1;

    return app.exec();
}

三、效果演示

相关推荐
闻缺陷则喜何志丹8 小时前
【C++贪心】P8769 [蓝桥杯 2021 国 C] 巧克力|普及+
c++·算法·蓝桥杯·洛谷
小岛前端9 小时前
Vue3 键盘快捷键的高效开发!
前端·vue.js·开源
杨小码不BUG9 小时前
灯海寻踪:开灯问题的C++精妙解法(洛谷P1161)
c++·算法·数学建模·位运算·浮点数·信奥赛·csp-j/s
杨小码不BUG9 小时前
心痛之窗:滑动窗口算法解爱与愁的心痛(洛谷P1614)
开发语言·c++·算法·滑动窗口·csp-j/s·多维向量
飞哥数智坊9 小时前
“成章”开源首更:3大体验优化,合集管理补齐!
人工智能·开源·ai编程
图灵信徒9 小时前
2024南京icpc区域赛详解与难点解释
c++·acm·icpc·算法竞赛
YxVoyager10 小时前
Qt C++ :XML文件处理工具 <QXml>模块
xml·c++·qt
扶尔魔ocy10 小时前
【QT常用技术讲解】QSerialPort串口开发,包含文件发送功能
qt
一只鱼^_10 小时前
力扣第470场周赛
数据结构·c++·算法·leetcode·深度优先·动态规划·启发式算法