libreCAD源码阅读笔记4

前言

总的来说,程序主窗口QC_ApplicationWindow使用QMdiArea作为多文档主界面,每个文档QC_MDIWindow使用RS_Document作为数据存储模型,QG_Graphicview作为每个文档窗口部件;QC_ApplicationWindow主窗口构造函数中使用工具类LC_ActionFactory生成各种程序Action,这些Action触发后都将调用QG_ActionHandler中的函数作为Action信号的槽函数。QG_ActionHandler槽函数根据信号源确定是什么Action操作类型,调用其成员函数setCurrentAction()产生具体Action对象,并调用其关联的QG_GraphicView也调用其自身setCurrentAction()将Action对象传递给RS_EventHandler。此后,当用户窗口绘图后,回调用当前的Action对象进行相关操作。

比如画线

  • 1 当主窗口点击画线按钮,触发画线的Action,根据下面代码,程序将会调用QG_ActionHandler的slotDrawLine()函数。
LC_ActionFactory.cpp : 120行
action = new QAction(tr("&2 Points"), agm->line);
action->setIcon(QIcon(":/icons/line_2p.svg"));
connect(action, SIGNAL(triggered()),
action_handler, SLOT(slotDrawLine()));
action->setObjectName("DrawLine");
a_map["DrawLine"] = action;
QG_ActionHandler.cpp : 1329行
void QG_ActionHandler::slotDrawLine() {setCurrentAction(RS2::ActionDrawLine);
}RS_ActionInterface* QG_ActionHandler::setCurrentAction(RS2::ActionType id) {......
switch (id) {......
case RS2::ActionDrawLine:a = new RS_ActionDrawLine(*document, *view);break;
......
if (a) {view->setCurrentAction(a);
}
  • 2 QG_ActionHandler生成具体Action后,将其传递给QG_GraphicView,作为当前需要执行的动作。
QG_GraphicView.cpp : 1054行
void QG_GraphicView::setCurrentQAction(QAction* q_action)
{eventHandler->setQAction(q_action);if (recent_actions.contains(q_action)){recent_actions.removeOne(q_action);}recent_actions.prepend(q_action);
}
  • 3 QG_GraphicView将此Action传递给RS_EventHandler。RS_EventHandler作为事件监听,当用户按下鼠标键或者鼠标移动时候,会触发器相应的函数。
QG_GraphicView.cpp : 288 行
void QG_GraphicView::mouseReleaseEvent(QMouseEvent* event)
{......switch (event->button()){case Qt::RightButton:......default:eventHandler->mouseReleaseEvent(event);break;}RS_DEBUG->print("QG_GraphicView::mouseReleaseEvent: OK");
}
RS_EventHandler.cpp : 115行
void RS_EventHandler::mouseReleaseEvent(QMouseEvent* e) {if(hasAction()){//    if (actionIndex>=0 && currentActions[actionIndex] &&//            !currentActions[actionIndex]->isFinished()) {RS_DEBUG->print("call action %s",currentActions.last()->getName().toLatin1().data());currentActions.last()->mouseReleaseEvent(e); /// 注意:调用具体Action的mouseReleaseEvent函数// Clean up actions - one might be finished nowcleanUp();e->accept();} else {if (defaultAction) {defaultAction->mouseReleaseEvent(e);} else {e->ignore();}}
}
  • 4 最后将事件传递给具体实体对象,实体对象完成自身绘制。
RS_ActionDrawLine.cpp : 164行
void RS_ActionDrawLine::mouseReleaseEvent(QMouseEvent* e)
{if (e->button() == Qt::LeftButton) {RS_Vector snapped = snapPoint(e);// Snapping to angle(15*) if shift key is pressedif ((e->modifiers() & Qt::ShiftModifier)&& getStatus() == SetEndpoint ) {snapped = snapToAngle(snapped, pPoints->data.startpoint, 15.);}RS_CoordinateEvent ce(snapped);coordinateEvent(&ce);}else if (e->button() == Qt::RightButton) {deletePreview();switch (getStatus()) {default:case SetStartpoint:init( getStatus() - 1);break;case SetEndpoint:next();break;}}
}

结束

学习记录下大体程序流程,其他还有很多细节内容需要进一步分析学习。比如libreCAD如何实现命令窗口绘制实体对象的?下次学习从RS_Commands类开始吧。

libreCAD源码阅读笔记4相关推荐

  1. libreCAD源码阅读笔记1

    libreCAD源码阅读笔记1 一 前言: 正如官网(https://www.librecad.org)所说,libreCAD是一个开源的CAD制图软件,可以运行在Windows.Apple.Linu ...

  2. libreCAD源码阅读笔记3

    libreCAD源码阅读笔记3 1 前言 打开RS_Document源码后,又出现了RS_EntityContainer.RS_Entity等一系列类,这好像就是libreCAD的数据模型,有具体的实 ...

  3. libreCAD源码阅读笔记2

    libreCAD源码阅读笔记2 1. 前言 继续学习QC_MDIWindow类.QG_ActionHandler类相关代码 2. QC_MDIWindow类 QC_MDIWindow类继承QT QMd ...

  4. Transformers包tokenizer.encode()方法源码阅读笔记

    Transformers包tokenizer.encode()方法源码阅读笔记_天才小呵呵的博客-CSDN博客_tokenizer.encode

  5. 源码阅读笔记 BiLSTM+CRF做NER任务 流程图

    源码阅读笔记 BiLSTM+CRF做NER任务(二) 源码地址:https://github.com/ZhixiuYe/NER-pytorch 本篇正式进入源码的阅读,按照流程顺序,一一解剖. 一.流 ...

  6. 代码分析:NASM源码阅读笔记

    NASM源码阅读笔记 NASM(Netwide Assembler)的使用文档和代码间的注释相当齐全,这给阅读源码 提供了很大的方便.按作者的说法,这是一个模块化的,可重用的x86汇编器, 而且能够被 ...

  7. CI框架源码阅读笔记4 引导文件CodeIgniter.php

    到了这里,终于进入CI框架的核心了.既然是"引导"文件,那么就是对用户的请求.参数等做相应的导向,让用户请求和数据流按照正确的线路各就各位.例如,用户的请求url: http:// ...

  8. Yii源码阅读笔记 - 日志组件

    2015-03-09 一 By youngsterxyf 使用 Yii框架为开发者提供两个静态方法进行日志记录: Yii::log($message, $level, $category); Yii: ...

  9. AQS源码阅读笔记(一)

    AQS源码阅读笔记 先看下这个类张非常重要的一个静态内部类Node.如下: static final class Node {//表示当前节点以共享模式等待锁static final Node SHA ...

最新文章

  1. Android面试题目之六---Handler,Looper和MessageQueue深入研究
  2. 系统设计经典题:手把手教你搭建一个IM(即时通讯) 系统
  3. 二十个CSS经典技巧
  4. 经典卷积网络进阶--ResNet详解
  5. C#LeetCode刷题之#389-找不同(Find the Difference)
  6. Python 加载二进制文件到 CkByteArray 对象
  7. win10系统无法自动修复启动解决方案
  8. android自定义壁纸制作,如何为Android制作自己的自定义壁纸 | MOS86
  9. 工商银行java script error windows7_Win8.1装工行网银提示"called runscript when not marked in progress"的解决方法...
  10. 指南针c语言程序,HMC5883L电子指南针单片机程序
  11. Jmeter创建大批量测试用户数据技巧
  12. 如何在sRGB和CIEXYZ之间进行转换
  13. Mac笔记本外接显示器竖屏设置
  14. CTFshow-卷王杯-简单的re(复现)
  15. 树莓派控制16路PWM输出的PCA9685模块
  16. 关闭potplayer播放器屏幕大量信息
  17. SDUT OJ 蟠桃记
  18. 图像拼接(十一):双摄像头实时拼接+stitching_detailed
  19. GD32f103 8M晶振改12M , 要修改的地方
  20. python 决策模型_python小白之路:第十七章 决策树模型

热门文章

  1. Codeforces 115 B Lawnmower【思维】
  2. java 函数(方法)
  3. DataGridView 单击选中一整行,只能单选,不能选择多行,只能选择一行
  4. CAS解决单点登录SSO
  5. OSI七层网络结构详解
  6. linux运维之批量升级
  7. git的使用和上传代码到gitee(码云) 教程
  8. For循环的简单实例
  9. 心得分享——c语言如何将多个字符串赋值给字符串数组(即c语言如何输入并储存多个字符串)
  10. 游戏浅谈1-传奇,跑跑卡丁车