开源 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_WINprocess->start("notepad.exe"); // Windows系统启动记事本
#elseprocess->start("gedit"); // Linux系统启动gedit
#endifif (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_WINprocess->start("cmd", QStringList() << "/c" << "dir"); // Windows执行dir命令
#elseprocess->start("ls", QStringList() << "-l"); // Linux执行ls -l命令
#endifif (!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的通信
2. 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资源文件加载QMLengine.load(QUrl(QStringLiteral("qrc:/main.qml")));if (engine.rootObjects().isEmpty()) // 检查QML是否加载成功return -1;return app.exec(); // 进入主事件循环
}
3. QML 界面详细分析
ApplicationWindow
ApplicationWindow {id: windowwidth: 800height: 600visible: truetitle: "Qt进程管理示例"
作用:创建主应用程序窗口
背景渐变
Rectangle {anchors.fill: parentgradient: Gradient {GradientStop { position: 0.0; color: "#2c3e50" }GradientStop { position: 1.0; color: "#3498db" }}
}
作用:创建从深蓝色到浅蓝色的垂直渐变背景
按钮组件分析
Button {Layout.fillWidth: truetext: "显示当前进程"font.pixelSize: 16background: Rectangle {color: parent.down ? "#27ae60" : "#2ecc71" // 按下时变深色radius: 8 // 圆角}contentItem: Text {text: parent.textfont: parent.fontcolor: "white"horizontalAlignment: Text.AlignHCenterverticalAlignment: Text.AlignVCenter}onClicked: {processManager.showCurrentProcess() // 调用C++函数}
}
详细分析:
Layout.fillWidth: true:在布局中填充宽度
background:自定义按钮背景,实现按下状态颜色变化
contentItem:自定义按钮文本样式
onClicked:按钮点击事件处理器,调用C++函数
输出显示区域
ScrollView {anchors.fill: parentanchors.margins: 5TextArea {id: outputAreareadOnly: true // 只读wrapMode: Text.Wrap // 自动换行color: "#ecf0f1" // 文字颜色font.pixelSize: 12font.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_OBJECTpublic: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_WINprocess->start("notepad.exe");
#elseprocess->start("gedit"); // Linux系统使用gedit
#endifif (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_WINprocess->start("cmd", QStringList() << "/c" << "dir");
#elseprocess->start("ls", QStringList() << "-l"); // Linux系统使用ls -l
#endifif (!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.12ApplicationWindow {id: windowwidth: 800height: 600visible: truetitle: "Qt进程管理示例"// 背景渐变Rectangle {anchors.fill: parentgradient: Gradient {GradientStop { position: 0.0; color: "#2c3e50" }GradientStop { position: 1.0; color: "#3498db" }}}ColumnLayout {anchors.fill: parentanchors.margins: 20spacing: 15// 标题Text {Layout.alignment: Qt.AlignHCentertext: "进程管理演示"font.pixelSize: 28font.bold: truecolor: "white"}// 按钮区域RowLayout {Layout.fillWidth: truespacing: 15// 显示当前进程按钮Button {Layout.fillWidth: truetext: "显示当前进程"font.pixelSize: 16background: Rectangle {color: parent.down ? "#27ae60" : "#2ecc71"radius: 8}contentItem: Text {text: parent.textfont: parent.fontcolor: "white"horizontalAlignment: Text.AlignHCenterverticalAlignment: Text.AlignVCenter}onClicked: {processManager.showCurrentProcess()}}// 打开记事本按钮Button {Layout.fillWidth: truetext: "打开记事本"font.pixelSize: 16background: Rectangle {color: parent.down ? "#2980b9" : "#3498db"radius: 8}contentItem: Text {text: parent.textfont: parent.fontcolor: "white"horizontalAlignment: Text.AlignHCenterverticalAlignment: Text.AlignVCenter}onClicked: {processManager.openNotepad()}}// 执行Dir命令按钮Button {Layout.fillWidth: truetext: "执行Dir命令"font.pixelSize: 16background: Rectangle {color: parent.down ? "#c0392b" : "#e74c3c"radius: 8}contentItem: Text {text: parent.textfont: parent.fontcolor: "white"horizontalAlignment: Text.AlignHCenterverticalAlignment: Text.AlignVCenter}onClicked: {processManager.executeDirCommand()outputArea.text = "执行命令中..."}}}// 信息显示区域Rectangle {Layout.fillWidth: trueLayout.preferredHeight: 100color: "#34495e"radius: 8border.color: "#7f8c8d"border.width: 2ScrollView {anchors.fill: parentanchors.margins: 5TextArea {id: infoAreareadOnly: truewrapMode: Text.Wrapcolor: "#ecf0f1"font.pixelSize: 14background: nullplaceholderText: "进程信息将显示在这里..."}}}// 命令输出区域Rectangle {Layout.fillWidth: trueLayout.fillHeight: truecolor: "#2c3e50"radius: 8border.color: "#7f8c8d"border.width: 2ScrollView {anchors.fill: parentanchors.margins: 5TextArea {id: outputAreareadOnly: truewrapMode: Text.Wrapcolor: "#ecf0f1"font.pixelSize: 12font.family: "Courier New"background: nullplaceholderText: "命令输出将显示在这里..."}}}// 状态栏Rectangle {Layout.fillWidth: trueLayout.preferredHeight: 30color: "#1abc9c"radius: 5Text {anchors.centerIn: parenttext: "Qt 5.12 进程管理示例 - 使用QProcess类"color: "white"font.pixelSize: 12}}}// 连接C++信号到QMLConnections {target: processManageronProcessInfoReady: {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);// 注册进程管理器到QMLProcessManager processManager;QQmlApplicationEngine engine;// 将C++对象暴露给QMLengine.rootContext()->setContextProperty("processManager", &processManager);// 加载QML文件engine.load(QUrl(QStringLiteral("qrc:/main.qml")));if (engine.rootObjects().isEmpty())return -1;return app.exec();
}
三、效果演示