0
点赞
收藏
分享

微信扫一扫

SkeyeGisMap 地图扩展(二)--处理事件

1、事件介绍

​SkeyeGisMap​​ 中事件的传递机制如下:

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、效果展示

SkeyeGisMap 地图扩展(二)--处理事件_Qt_02

源码地址: ​​https://gitee.com/visual-opening/skeyegismap/tree/master/coremap/example​​

举报

相关推荐

0 条评论