libreCAD源码阅读笔记4

您所在的位置:网站首页 opencascade开发 libreCAD源码阅读笔记4

libreCAD源码阅读笔记4

2023-02-12 03:17| 来源: 网络整理| 查看: 265

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 now cleanUp(); 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 pressed if ((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类开始吧。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3