17-Mediator

       Mediator模式:用一个中介对象来封装一系列的对象交互,使各对象不需要显示地相互调用。简单而言就是封装了多个对象之间的复杂操作,使的两个对象解耦!

       http://www.jdon.com/designpatterns/mediator.htm

       http://gary0416.iteye.com/blog/913462

       以上两个连接都是不错的参考,例子比较很好理解!

Mediator模式在事件驱动类应用中比较多,例如界面设计GUI.;聊天,消息传递等,在聊天应用中,需要有一个MessageMediator,专门负责request/reponse之间任务的调节.

MVC是J2EE的一个基本模式,View Controller是一种Mediator,它是Jsp和服务器上应用程序间的Mediator.

)这些需要后续逐步验证、熟悉!


       由于没有实际的项目参与,虽然有一些例子,但是这些例子毕竟是示例,没有实际的可操作性,对于实际情况需要实际处理!



【直流微电网】径向直流微电网的状态空间建模与线性化:一种耦合DC-DC变换器状态空间平均模型的方法 (Matlab代码实现)内容概要:本文介绍了径向直流微电网的状态空间建模与线性化方法,重点提出了一种基于耦合DC-DC变换器状态空间平均模型的建模策略。该方法通过对系统中多个相互耦合的DC-DC变换器进行统一建模,构建出整个微电网的集中状态空间模型,并在此基础上实施线性化处理,便于后续的小信号分析与稳定性研究。文中详细阐述了建模过程中的关键步骤,包括电路拓扑分析、状态变量选取、平均化处理以及雅可比矩阵的推导,最终通过Matlab代码实现模型仿真验证,展示了该方法在动态响应分析和控制器设计中的有效性。; 适合人群:具备电力电子、自动控制理论基础,熟悉Matlab/Simulink仿真工具,从事微电网、新能源系统建模与控制研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①掌握直流微电网中多变换器系统的统一建模方法;②理解状态空间平均法在非线性电力电子系统中的应用;③实现系统线性化并用于稳定性分析与控制器设计;④通过Matlab代码复现和扩展模型,服务于科研仿真与教学实践。; 阅读建议:建议读者结合Matlab代码逐步理解建模流程,重点关注状态变量的选择与平均化处理的数学推导,同时可尝试修改系统参数或拓扑结构以加深对模型通用性和适应性的理解。
void GeneralGraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { //没有按住Ctrl键时,拖动框时保存框的位置 auto isPressCtrl = event->modifiers() & Qt::Modifier::CTRL; if (this->mIsPressLeftButton && this->mMoveMementroModel && this->mMoveGrphicsItemPos && !isPressCtrl) { this->PushUnDoCmd(this->mMoveMementroModel); } this->mMoveMementroModel = nullptr; this->mIsPressLeftButton = false; this->SetGraphicsItemPosChange(false); this->mCoordinator->GetActionHandler().MouseReleaseEvent(event); QGraphicsScene::mouseReleaseEvent(event); //由于大框、中框、小框的pos不一定为0,需要都转化成基于scene(图片)原点的坐标存储, if (!this->mDrawingModel.isDrawingMode()) { if (this->mChangedItemsMap.count() > 0) { QList<QSharedPointer<GeneralGraphicsBaseModel>> updateItemsModelList; for (auto& key : this->mChangedItemsMap.keys()) { auto changedItem = this->mChangedItemsMap[key]; if (changedItem) { if (changedItem->GetModel()->regionType == GeneralGraphicsRegionType::ElementOutRegion) { for (auto& citem : changedItem->childItems()) { auto childItem = static_cast<GeneralGraphicsBaseItem *>(citem); if (childItem) { childItem->TransToSceneVertexs(); updateItemsModelList.append(childItem->GetModel()); } } } else if (changedItem->GetModel()->regionType == GeneralGraphicsRegionType::BoardRegion) { for (auto& elementOutItem : changedItem->childItems()) { for (auto& citem : elementOutItem->childItems()) { auto childItem = static_cast<GeneralGraphicsBaseItem *>(citem); if (childItem) { childItem->TransToSceneVertexs(); updateItemsModelList.append(childItem->GetModel()); } } auto eGItem = static_cast<GeneralGraphicsBaseItem *>(elementOutItem); if (eGItem) { eGItem->TransToSceneVertexs(); updateItemsModelList.append(eGItem->GetModel()); } } } changedItem->TransToSceneVertexs(); updateItemsModelList.append(changedItem->GetModel()); } } //发送更新的图元信息信号 auto mediator = this->mCoordinator->GetMediator(); if (mediator) { GG_SDK_LOG_TRACE("SigGGMediatorUpdateGraphicsItem %d", updateItemsModelList.count()); emit mediator->SigGGMediatorUpdateGraphicsItem(updateItemsModelList); } } this->mChangedItemsMap.clear(); } //发送选中的图元信息信号 auto mediator = this->mCoordinator->GetMediator(); if (mediator && this->selectedItems().count() < 10) { auto resList = GeneralGraphicsUtils::GetSelectedGraphicsItemIndexFromScene(this->selectedItems()); if (!resList.isEmpty()) { emit mediator->SigGGMediatorSelectItems(resList); } } GG_SDK_LOG_TRACE("graphics item count: %d", this->mGrpahicsItemsMap.count()); qDebug(u8"graphics item count: %d", this->mGrpahicsItemsMap.count()); }讲解一下这个代码,是做什么的逐行讲一下
10-23
<think>我们有一个C++函数,它是QGraphicsScene子类的mouseReleaseEvent事件处理函数。 主要处理鼠标释放事件时的逻辑,包括保存移动的图元位置、更新图元坐标、发送信号等。 逐行讲解如下: 1. `void GeneralGraphicsScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)` 这是函数声明,重写了QGraphicsScene的mouseReleaseEvent方法。 2. `//没有按住Ctrl键时,拖动框时保存框的位置` 注释:说明在未按Ctrl键的情况下拖动框,会保存框的位置。 3. `auto isPressCtrl = event->modifiers() & Qt::Modifier::CTRL;` 判断事件发生时是否按下了Ctrl键,将结果保存在isPressCtrl中。 4. `if (this->mIsPressLeftButton && this->mMoveMementroModel && this->mMoveGrphicsItemPos && !isPressCtrl)` 条件判断:如果左键按下标志为真,存在移动的备忘录模型(mMoveMementroModel),存在移动的图元位置(mMoveGrphicsItemPos),并且没有按下Ctrl键,则执行下面的语句。 5. `{ this->PushUnDoCmd(this->mMoveMementroModel); }` 如果满足上述条件,则执行撤销命令的入栈操作(保存当前状态,以便撤销)。 6. `this->mMoveMementroModel = nullptr;` 将移动的备忘录模型指针置空。 7. `this->mIsPressLeftButton = false;` 将左键按下标志置为false。 8. `this->SetGraphicsItemPosChange(false);` 设置图元位置改变标志为false。 9. `this->mCoordinator->GetActionHandler().MouseReleaseEvent(event);` 调用协调器(mCoordinator)中的ActionHandler的MouseReleaseEvent方法,继续处理鼠标释放事件。 10. `QGraphicsScene::mouseReleaseEvent(event);` 调用父类的mouseReleaseEvent方法,确保基类的事件处理也被执行。 11. `//由于大框、中框、小框的pos不一定为0,需要都转化成基于scene(图片)原点的坐标存储,` 注释:说明需要将图元的位置转换为基于场景(scene)原点的坐标。 12. `if (!this->mDrawingModel.isDrawingMode())` 判断当前是否处于绘制模式,如果不是绘制模式,则执行下面的逻辑。 13. `{ if (this->mChangedItemsMap.count() > 0)` 如果存在发生改变的图元(mChangedItemsMap中有记录),则执行下面的代码块。 14. `QList<QSharedPointer<GeneralGraphicsBaseModel>> updateItemsModelList;` 声明一个列表,用于存储需要更新的图元模型。 15. `for (auto& key : this->mChangedItemsMap.keys())` 遍历mChangedItemsMap中的所有键(即发生改变的图元)。 16. `auto changedItem = this->mChangedItemsMap[key];` 获取当前键对应的图元。 17. `if (changedItem)` 如果图元存在,则继续处理。 18. `if (changedItem->GetModel()->regionType == GeneralGraphicsRegionType::ElementOutRegion)` 如果图元的区域类型是ElementOutRegion(可能是外部区域),则处理其子项。 19. `for (auto& citem : changedItem->childItems())` 遍历该图元的所有子项。 20. `auto childItem = static_cast<GeneralGraphicsBaseItem *>(citem);` 将子项转换为GeneralGraphicsBaseItem类型。 21. `if (childItem) { ... }` 如果转换成功,则调用子项的TransToSceneVertexs方法(将坐标转换为场景坐标),并将该子项的模型加入到更新列表中。 22. `else if (changedItem->GetModel()->regionType == GeneralGraphicsRegionType::BoardRegion)` 如果图元的区域类型是BoardRegion(可能是板区域),则处理其子项(这里有两层嵌套:先取elementOutItem,再取elementOutItem的子项)。 23. 对于BoardRegion,首先遍历changedItem的每个子项(elementOutItem),然后遍历每个elementOutItem的子项(citem),将其转换为GeneralGraphicsBaseItem,并调用TransToSceneVertexs,然后将模型添加到更新列表。 然后,对elementOutItem本身也进行同样的转换和添加。 24. `changedItem->TransToSceneVertexs();` 最后,对changedItem本身进行坐标转换。 25. `updateItemsModelList.append(changedItem->GetModel());` 将changedItem的模型添加到更新列表。 26. 循环结束后,检查是否有需要发送的信号: `auto mediator = this->mCoordinator->GetMediator();` 获取中介者(mediator)。 27. `if (mediator) { ... }` 如果中介者存在,则发送信号SigGGMediatorUpdateGraphicsItem,通知更新图元,并传递更新列表。 28. `this->mChangedItemsMap.clear();` 清空已改变图元的映射。 29. 在绘制模式判断的代码块结束后,还有一段发送选中图元信息的代码: `auto mediator = this->mCoordinator->GetMediator();` 再次获取中介者(注意,这里可能和上面的是同一个,但重新获取一次)。 30. `if (mediator && this->selectedItems().count() < 10)` 如果中介者存在且选中的图元数量小于10(避免选中太多时发送大量数据)。 31. `auto resList = GeneralGraphicsUtils::GetSelectedGraphicsItemIndexFromScene(this->selectedItems());` 通过工具函数获取选中图元的索引列表。 32. `if (!resList.isEmpty()) { emit mediator->SigGGMediatorSelectItems(resList); }` 如果列表非空,则发送选中的图元索引列表信号。 33. 最后两行日志输出: `GG_SDK_LOG_TRACE("graphics item count: %d", this->mGrpahicsItemsMap.count());` `qDebug(u8"graphics item count: %d", this->mGrpahicsItemsMap.count());` 输出当前场景中图元的总数量(通过mGrpahicsItemsMap的计数)。 总结:这个函数主要处理鼠标释放事件,包括: - 处理撤销操作(在未按Ctrl的情况下移动图元) - 重置一些状态(如移动备忘录、左键按下标志等) - 调用父类和协调器的相关方法 - 更新发生改变的图元坐标(转换为场景坐标)并通知更新 - 发送选中的图元信息(当选中数量小于10时) - 记录日志 注意:代码中涉及多层图元结构(如BoardRegion包含ElementOutRegion,ElementOutRegion包含其他子项),需要递归处理坐标转换。 </think>这段代码是Qt框架中`QGraphicsScene`子类的鼠标释放事件处理函数,主要实现图形交互中的状态保存、坐标转换和事件传递功能。以下是逐行分析: ### 核心逻辑逐行解析: 1. **`auto isPressCtrl = ...`** 检测是否按下了Ctrl键,用于组合键操作判断。 2. **`if (this->mIsPressLeftButton && ...)`** 满足三个条件时触发撤销栈操作: - 左键按下状态为真 (`mIsPressLeftButton`) - 存在移动的图元备忘录 (`mMoveMementroModel`) - 图元位置发生变化 (`mMoveGrphicsItemPos`) - 未按Ctrl键 → 调用`PushUnDoCmd()`保存当前状态到撤销栈 3. **状态重置** ```cpp this->mMoveMementroModel = nullptr; // 清空移动备忘录 this->mIsPressLeftButton = false; // 重置左键按下标志 this->SetGraphicsItemPosChange(false); // 标记位置变化结束 ``` 4. **事件传递** ```cpp this->mCoordinator->GetActionHandler().MouseReleaseEvent(event); // 通知协调器 QGraphicsScene::mouseReleaseEvent(event); // 调用父类默认处理 ``` 5. **坐标转换核心逻辑** ```cpp if (!this->mDrawingModel.isDrawingMode()) { // 非绘制模式下执行 if (this->mChangedItemsMap.count() > 0) { // 存在变更图元时 // 遍历所有变更图元 for (auto& key : this->mChangedItemsMap.keys()) { // 处理ElementOutRegion类型(外层区域) if (regionType == ElementOutRegion) { for (子图元) { childItem->TransToSceneVertexs(); // 转换子图元坐标到场景坐标系 updateItemsModelList.append(...); // 加入更新列表 } } // 处理BoardRegion类型(主板区域) else if (regionType == BoardRegion) { for (外层图元) { for (内层子图元) { // 双层嵌套转换 childItem->TransToSceneVertexs(); updateItemsModelList.append(...); } eGItem->TransToSceneVertexs(); // 外层图元自身转换 } } changedItem->TransToSceneVertexs(); // 当前图元坐标转换 updateItemsModelList.append(...); } // 发送更新信号 emit mediator->SigGGMediatorUpdateGraphicsItem(updateItemsModelList); this->mChangedItemsMap.clear(); // 清空变更记录 } } ``` 6. **选中图元处理** ```cpp if (mediator && selectedItems().count() < 10) { // 选中少于10个图元时 auto resList = GetSelectedGraphicsItemIndexFromScene(...); // 获取选中项索引 emit mediator->SigGGMediatorSelectItems(resList); // 发送选中信号 } ``` 7. **日志输出** ```cpp GG_SDK_LOG_TRACE("graphics item count: %d", ...); // 输出图元总数 qDebug(u8"graphics item count: %d", ...); // 调试信息输出 ``` ### 核心功能总结: - **状态管理**:记录鼠标操作状态,实现撤销/重做功能 - **坐标转换**:将嵌套图元(主板/外层/子图元)的坐标统一转换为场景坐标系 - **事件传递**: - 向上传递鼠标事件给父类 - 通过`mediator`发送两类信号: `SigGGMediatorUpdateGraphicsItem` - 图元坐标更新信号 `SigGGMediatorSelectItems` - 图元选中状态信号 - **性能优化**:限制选中信号发送条件(<10个图元),避免大数据量传输
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值