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…