【QA】Qt中有哪些命令模式的运用?
在 C++/Qt 中,命令模式(Command Pattern)的实现通常用于封装操作请求、支持撤销/重做(Undo/Redo)或解耦调用者与接收者。以下是几种常见的实现方式及示例:
1. Qt 的 QUndoCommand 和 QUndoStack(内置的撤销/重做框架)
这是 Qt 中命令模式的最典型实现,用于管理可撤销的操作。
-
核心类:
QUndoCommand:基类,表示一个可撤销的命令,需实现undo()和redo()。QUndoStack:管理命令历史记录的栈,支持撤销/重做。
-
示例代码:
class AddItemCommand : public QUndoCommand { public:AddItemCommand(QListWidget *listWidget, const QString &text, QUndoCommand *parent = nullptr): QUndoCommand("Add Item", parent), m_listWidget(listWidget), m_text(text) {}void redo() override {m_listWidget->addItem(m_text);}void undo() override {QListWidgetItem *item = m_listWidget->takeItem(m_listWidget->count() - 1);delete item;}private:QListWidget *m_listWidget;QString m_text; };// 使用示例 QUndoStack undoStack; QListWidget listWidget;// 执行命令 undoStack.push(new AddItemCommand(&listWidget, "New Item"));// 撤销 undoStack.undo();// 重做 undoStack.redo();
2. Qt 的 QAction(动作框架)
QAction 封装了用户触发的操作(如菜单项点击),可绑定到多个控件(菜单、工具栏按钮等),本质上是命令模式的轻量级应用。
-
核心思想:
QAction将操作(如“复制”)封装为对象,通过信号triggered()触发执行。- 可绑定快捷键、图标、文本等,统一管理状态(启用/禁用)。
-
示例代码:
QAction *copyAction = new QAction("Copy", this); copyAction->setShortcut(QKeySequence::Copy); connect(copyAction, &QAction::triggered, this, &MyWidget::copy);// 将动作添加到菜单和工具栏 menuBar()->addAction(copyAction); toolBar()->addAction(copyAction);
3. 自定义命令接口(通用实现)
若需更灵活的控制,可自定义命令基类,并手动管理命令队列。
-
实现步骤:
- 定义抽象命令接口。
- 实现具体命令类。
- 使用调用者(Invoker)触发命令。
-
示例代码:
// 1. 定义命令接口 class Command { public:virtual ~Command() {}virtual void execute() = 0;virtual void undo() = 0; };// 2. 具体命令类:改变文本 class ChangeTextCommand : public Command { public:ChangeTextCommand(QLabel *label, const QString &newText): m_label(label), m_oldText(label->text()), m_newText(newText) {}void execute() override {m_label->setText(m_newText);}void undo() override {m_label->setText(m_oldText);}private:QLabel *m_label;QString m_oldText;QString m_newText; };// 3. 调用者(如按钮点击触发命令) QPushButton button("Change Text"); QLabel label("Original Text"); Command *cmd = new ChangeTextCommand(&label, "New Text");QObject::connect(&button, &QPushButton::clicked, [cmd]() {cmd->execute(); });
4. 信号与槽的封装
通过将槽函数包装为命令对象,结合 QObject::connect 实现解耦。
-
示例场景:
- 将复杂操作封装为命令对象,通过信号触发执行。
- 使用
QSharedPointer管理命令生命周期。
class CommandWrapper : public QObject {Q_OBJECT public:CommandWrapper(Command *cmd) : m_cmd(cmd) {}public slots:void execute() { m_cmd->execute(); }void undo() { m_cmd->undo(); }private:QSharedPointer<Command> m_cmd; };// 连接信号到命令 CommandWrapper wrapper(new ChangeTextCommand(&label, "New Text")); QObject::connect(&button, &QPushButton::clicked, &wrapper, &CommandWrapper::execute);
5. 宏命令(Composite Command)
将多个命令组合成一个宏命令,实现批量操作。
- 示例代码:
class MacroCommand : public Command { public:void addCommand(Command *cmd) {m_commands.append(cmd);}void execute() override {for (auto cmd : m_commands) {cmd->execute();}}void undo() override {for (auto it = m_commands.rbegin(); it != m_commands.rend(); ++it) {(*it)->undo();}}private:QList<Command*> m_commands; };// 使用示例 MacroCommand *macro = new MacroCommand; macro->addCommand(new Command1); macro->addCommand(new Command2); macro->execute();
总结
在 Qt 中应用命令模式的核心思想是:
- 封装操作:将请求封装为对象(如
QUndoCommand)。 - 解耦调用者与接收者:通过信号/槽或直接调用命令接口。
- 支持扩展:通过组合或继承实现复杂逻辑(如宏命令)。
根据需求选择合适的方式,若需要撤销/重做,优先使用 QUndoStack;若需简单解耦,可通过 QAction 或自定义命令类实现。
相关文章:
【QA】Qt中有哪些命令模式的运用?
在 C/Qt 中,命令模式(Command Pattern)的实现通常用于封装操作请求、支持撤销/重做(Undo/Redo)或解耦调用者与接收者。以下是几种常见的实现方式及示例: 1. Qt 的 QUndoCommand 和 QUndoStack(内…...
【连续自然数的和,双指针找区间】
对一个给定的正整数 MM,求出所有的连续的正整数段(每一段至少有两个数),这些连续的自然数段中的全部数之和为 MM。 例子:19981999200020012002100001998199920002001200210000,所以从 19981998 到 2002200…...
Cocos Creator Shader入门实战(五):材质的了解、使用和动态构建
引擎:3.8.5 您好,我是鹤九日! 回顾 前面的几篇文章,讲述的主要是Cocos引擎对Shader使用的一些固定规则,这里汇总下: 一、Shader实现基础是OpenGL ES可编程渲染管线,开发者只需关注顶点着色器和…...
vue设置自定义logo跟标题
准备 Logo 图片 将自定义的 Logo 图片(如 logo.png)放置在项目的 public文件夹下。 使用环境变量设置 Logo 和标题(可选) 创建或修改 .env 文件 在项目根目录下创建或修改 .env 文件,添加以下内容: VITE_A…...
Linux 账号和权限管理命令选项解释
用户账号文件 配置文件 /etc/passwd:用于保存用户 输出如下: root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin 每一行代表一个用户&…...
尝试在软考65天前开始成为软件设计师-计算机网络
OSI/RM 七层模型 层次名功能主要协议7应用层实现具体应用功能 FTP(文件传输)、HTTP、Telnet、 POP3(邮件)SMTP(邮件) ------- DHCP、TFTP(小文件)、 SNMP、 DNS(域名) 6表示层数据格式,加密,压缩.....5会话层建立,管理&终止对话4传输层端到端连接TCP,UDP3网络层分组传输&a…...
VMware主机换到高配电脑,高版本系统的问题
原来主机是i3 ,windows7系统,vmware 14.0,虚机系统是ubuntu 14.04。目标新机是i7 14700KF,windows11系统。原以为安装虚拟机,将磁盘文件,虚拟机配置文件拷贝过去可以直接用。 新目标主机先安装了vmware 15,运行原理虚机࿰…...
2025年3月 CCF GESP C++ 二级 真题解析
1. 单选题(每题2分,共30分) 第1题 试题:2025年春节有两件轰动全球的事件,一个是DeepSeek横空出世,另一个是贺岁片《哪吒2》票房惊人,入了全球票房榜。下面关于DeepSeek与《哪吒2》的描述成立的是( )。 A. 《哪吒2》是一…...
Nginx请求头Hos头攻击
HTTP请求头中的Host字段用于指定客户端请求的目标主机名(域名/IP)。当Nginx作为反向代理时,可利用该字段进行访问控制,防止非法域名或IP直接访问服务。 解决方法:添加判断请求头,如果不是指定请求头&#…...
2025年03月10日人慧前端面试(外包滴滴)
目录 普通函数和箭头函数的区别loader 和 plugin 的区别webpack 怎么实现分包,为什么要分包webpack 的构建流程变量提升react 开发中遇到过什么问题什么是闭包vue 开发中遇到过什么问题vue中的 dep 和 watcher 的依赖收集是什么阶段什么是原型链react setState 是同…...
【Linux内核系列】:动静态库详解
🔥 本文专栏:Linux 🌸作者主页:努力努力再努力wz 💪 今日博客励志语录: 有些鸟儿是注定是关不住的,因为它们的每一片羽翼都沾满了自由的光辉 ★★★ 本文前置知识: 编译与链接的过程…...
maptalks图层交互 - 模拟 Tooltip
maptalks图层交互 - 模拟 Tooltip 图层交互-模拟tooltip官方文档 <!DOCTYPE html> <html><meta charsetUTF-8 /><meta nameviewport contentwidthdevice-width, initial-scale1 /><title>图层交互 - 模拟 Tooltip</title><style typet…...
windows环境下NER Python项目环境配置(内含真的从头安的perl配置)
注意 本文是基于完整项目的环境配置,即本身可运行项目你拿来用 其中有一些其他问题,知道的忽略即可 导入pycharm基本包怎么下就不说了(这个都问?给你一拳o(`ω*)o) 看perl跳转第5条 1.predict报错多个设备…...
IDEA批量替换项目下所有文件中的特定内容
文章目录 1. 问题引入2. 批量替换项目下所有文件中的特定内容2.1 右键项目的根目录,点击在文件中替换2.2 输入要替换的内容 3. 解决替换一整行文本后出现空行的问题4. 增加筛选条件提高匹配的精确度 更多 IDEA 的使用技巧可以查看 IDEA 专栏: IDEA 1. 问…...
【计算机网络】网络编程
文章目录 1. 客户端/服务器2. TCP/UDP协议3. 网络编程套接字-socket3.1 API的使用3.1 DatagramScoket类3.1 DatagramScoket类 4. 通过UDP实现回显服务器程序4.1 服务器代码4.2 客户端代码4.3 代码执行过程4.4 通过UDP实现翻译客户端 5. 通过TCP实现回显服务器5.1 服务器代码5.2…...
Django 中@login_required 配置详解
在 Django 中对 login_required 进行配置,主要涉及全局配置和视图函数局部配置两方面,下面为你详细介绍配置方法。 全局配置 全局配置主要是设定默认的登录 URL,也就是当未登录用户尝试访问被 login_required 装饰的视图时,会被…...
【408--复习笔记】数据结构
【408--复习笔记】数据结构 1.绪论2.线性表3.栈、队列、数组4.串5.树与二叉树6.图7.查找8.排序 1.绪论 2.线性表 3.栈、队列、数组 4.串 5.树与二叉树 6.图 7.查找 8.排序...
Android <queries>声明的作用和配置方法
在Android应用中使用resolveActivity方法会提示在清单文件中添加标签,下面我们就看下声明的作用和配置方法: 一、queries 声明的作用 在Android 11及更高版本中,声明被引入以控制应用之间的交互。通过在AndroidManifest.xml中添加标签&…...
C++多线程编程:从创建到管理的终极指南
在高性能计算时代,掌握多线程编程是提升程序效率的必修课!本文将手把手教你如何用C++11标准库轻松创建和管理线程,告别单线程的“龟速”,让代码跑出多核CPU的性能! 一、多线程为何重要? 充分利用多核CPU:现代计算机普遍支持多核并行,多线程可让程序性能指数级提升。提升…...
【蓝桥杯】4535勇闯魔堡(多源BFS + 二分)
思路 k有一个范围(0到怪物攻击的最大值),求满足要求的k的最小值。很明显的二分套路。 关键是check函数怎么写,我们需要找到一条从第一行到最后一行的路径,每一次可以从上下左右四个方向前进,那么我么可以用…...
HTML图像标签的详细介绍
1. 常用图像格式 格式特点适用场景JPEG有损压缩,文件小,不支持透明适合照片、复杂图像PNG无损压缩,支持透明(Alpha通道)适合图标、需要透明背景的图片GIF支持动画,最多256色简单动画、低色彩图标WebP谷歌开…...
Chapter 4-15. Troubleshooting Congestion in Fibre Channel Fabrics
show zone member: Shows the name of the zone to which a device belongs to. This command can be used to find the victims of a culprit device or vice versa. 显示设备所属的区域名称。该命令可用于查找罪魁祸首设备的受害者,反之亦然。 show zone active: Shows the…...
QT三 自定义控件
一 自定义控件 现在的需求是这样: 假设我们要在QWidget 上做定制,这个定制包括了关于 一些事件处理,意味着要重写QWidget的一些代码,这是不实际的,因此我们需要自己写一个MyWidget继承QWidget,然后再MyWi…...
在 ASP .NET Core 9.0 中使用 Scalar 创建漂亮的 API 文档
示例代码:https://download.csdn.net/download/hefeng_aspnet/90407900 Scalar 是一款可帮助我们为 API 创建精美文档的工具。与感觉有些过时的默认 Swagger 文档不同,Scalar 为 API 文档提供了全新而现代的 UI。其简洁的设计让开发人员可以轻松找到测试…...
用于 RGB-D 显著目标检测的点感知交互和 CNN 诱导的细化网络(问题)
摘要 问题一:但在对自模态和跨模态的全局长距离依赖关系进行建模方面仍显不足。什么意思? 自模态(Intra-modal)全局依赖:在同一模态内,长距离像素之间的信息交互对于理解全局背景很重要,但 CN…...
python3 -m http.sever 8080加载不了解决办法
解决方法很多,本文设置各种处理方法,逻辑上需要根据你的自身情况选择 我会告诉你遇到这种问题怎么做,根据具体症状处理 如需转载,标记出处 背景: 1。如图 2.。域名访问不了 http://www.meiduo.site:8080/register.ht…...
Oracle数据库性能优化全攻略:十大关键方向深度解析与实践指南
文章目录 一、SQL查询优化二、索引优化三、内存管理四、I/O优化五、分区表与分区索引六、并行处理七、统计信息管理八、锁与并发控制九、数据库参数调优十、应用设计优化结论 在当今数据驱动的时代,数据库的性能优化成为了确保企业应用高效运行的关键。Oracle作为业…...
第十一章 | 智能合约主网部署与验证详解
📚 第十一章 | 智能合约主网部署与验证详解 ——让你的合约真正上线、公开、透明! ✅ 本章导读 前面我们写了各种合约,ERC20、NFT、DAO…… 但只在本地测试或测试网上部署运行,项目还没“上链”! 主网上线部署&#…...
蓝桥杯 回文数组
问题描述 小蓝在无聊时随机生成了一个长度为 n 的整数数组,数组中的第 i 个数为 a_i,他觉得随机生成的数组不太美观,想把它变成回文数组,也就是对于任意 i ∈ [1, n] 满足: a_i a_(n-i1)小蓝一次操作可以指定相邻的…...
windows清除电脑开机密码,可保留原本的系统和资料,不重装系统
前言 很久的一台电脑没有使用了,开机密码忘了,进不去系统 方法 1.将一个闲置u盘设置成pe盘(注意,这个操作会清空原来u盘的数据,需要在配置前将重要数据转移走,数据无价,别因为配置这个丢了重…...
