1、事件介绍
SkeyeGisMap
中事件的传递机制如下:
- 1、首先创立
QGuiApplication
并启动主事件循环。 - 2、接着创立
MapItem
承受来自窗口的事件。 - 3、
MapItem
将会把QEvent
转换成MapEvent
并传递给地图根节点MapRootNode
。 4、
MapRootNode
遍历所有图层节点并依据MapLayerNode
的视觉层级顺次向下传递。留神:
WorldLayer
位于所有TransformLayer
之上, 因而会优先取得事件。另一方面, 每一个图层节点都有本人范畴
MapLayerNode::boundingRect()
, 因而, 对于范畴之外的事件将间接向下传递。如果某个图层节点承受了事件
MapEvent::isAccepeted()
, 事件将进行传递。
5、
MapLayerNode
遍历所有形态节点并依据MapShapeNode
的视觉层级顺次向下传递。如果某个形态节点承受了事件, 事件也将进行传递(即代表该层承受了事件)。
2、具体实施
当初, 咱们筹备实现一个可挪动的多边形:
class MovablePolygon: public MapPolygonNode{public: MovablePolygon(const QPolygonF &polygon, const QColor &borderColor, int borderWidth, const QColor &fillColor) : MapPolygonNode(polygon, borderColor, borderWidth, fillColor) { } void translate(const QPointF &offset) { auto polygon = points(); polygon.translate(offset); setPoints(polygon); } virtual void mousePresseEvent(MapMouseEvent *event) override { MapShapeNode::mousePresseEvent(event); m_startPosition = event->displayCoord(); event->accepted(); } virtual void mouseMoveEvent(MapMouseEvent *event) override { MapShapeNode::mouseMoveEvent(event); translate(event->displayCoord() - m_startPosition); m_startPosition = event->displayCoord(); event->accepted(); } virtual void mouseReleaseEvent(MapMouseEvent *event) override { MapShapeNode::mouseReleaseEvent(event); event->accepted(); }private: QPointF m_startPosition;};
能够看到, 咱们的事件处理和 QWidget
或 QQuickItem
简直统一。
只需重写 mousePresseEvent()
鼠标按下事件, mouseMoveEvent()
鼠标挪动事件, mouseReleaseEvent()
鼠标开释事件。
不过要留神的是: 所有重写的事件须要调用其基类实现, 并且, 如果不想事件持续传递, 则须要承受事件 event->accepted()
。
并且, 图层节点不会解决图层边界之外的事件, 相应的形态也会被剪裁, 要敞开请应用 MapLayerNode::setClip()
。
和上一个示例相似, 其地图扩大如下:
class HandingEventsExample: public MapItem{public: HandingEventsExample() { setProcessFlag(MapItem::ProcessFlag::UsePreLoadProcess); } virtual void preLoadProcess() override { auto assistant = rootMap()->assistant(); //创立一个矩形 auto leftTop = assistant->mapToDisplay(CoordinateReference::lonlatToWorld({ 40.0365, 90.7359 })); auto leftBottom = assistant->mapToDisplay(CoordinateReference::lonlatToWorld({ 24.9160, 94.8131 })); auto rightTop = assistant->mapToDisplay(CoordinateReference::lonlatToWorld({ 43.1443, 116.2369 })); auto rightBottom = assistant->mapToDisplay(CoordinateReference::lonlatToWorld({ 26.7637, 116.6262 })); QPolygonF polygon; polygon << leftTop << leftBottom << rightBottom << rightTop << leftTop; //增加到最初一个图层中 auto lastLayer = rootMap()->lastLayer(); if (lastLayer) { lastLayer->setBackground(QColor("#a000b800")); lastLayer->appendShape(new MovablePolygon(polygon, Qt::black, 2, QColor("#a000a8f3"))); lastLayer->appendShape(new MovablePolygon(polygon, Qt::black, 2, QColor("#a000a8f3"))); } }};
另外要提一点, MapPolygonNode
默认实现了 mouseEnterEvent / mouseLeaveEvent
的成果, 如果不须要则重写即可。
3、成果展现
源码地址: https://gitee.com/visual-open...