共计 2562 个字符,预计需要花费 7 分钟才能阅读完成。
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…