之前我们提到过: 在任何时候都不要直接操作地图节点(即 Map*Node ), 因为地图节点位于渲染线程。
但是, 如果本身处于渲染线程中, 则没有任何限制。
SkeyeGisMap 提供两个渲染线程调用 MapItem::preLoadProcess() 和 MapItem::processUserEvent()。
具体可见: https://openskeye.blog.csdn.net/article/details/127495496
在很多时候, 我们需要操作或访问地图节点, 此时自定义事件便派上用场了。
首先, 我们要实现一个自己的事件:
class BlinkEvent : public MapEvent
{
public:
const static MapEvent::EventType BlinkEventType = MapEvent::EventType::UserEvent + 1;
BlinkEvent() : MapEvent(BlinkEventType) { }
};
这里实现了一个简单的闪烁事件, 注意 所有的地图事件都需要继承 MapEvent。
接着, 我们在地图中启用自定义事件, 需要设置 MapItem::ProcessFlag::UseUserEvent:
CustomEventsExample()
{
setProcessFlags(ProcessFlag::UsePreLoadProcess | ProcessFlag::UseUserEvent);
QTimer *blikTimer = new QTimer(this);
connect(blikTimer, &QTimer::timeout, this, [this]{ pushEvent(new BlinkEvent()); });
blikTimer->start(500);
}
记住, 使用 MapItem::pushEvent() 向地图中推送事件。
同样的, 在 MapItem::preLoadProcess() 中创建自己的节点:
virtual void preLoadProcess() override
{
auto assistant = rootMap()->assistant();
//创建一个中心点
auto center = assistant->mapToDisplay(CoordinateReference::lonlatToWorld({ 31.9387, 118.8137 }));
m_point = new MapPointNode(this, center, 40000, QColor("#e000a8f3"));
//添加到最后一个图层中
auto lastLayer = rootMap()->lastLayer();
if (lastLayer) {
lastLayer->appendShape(m_point);
}
}
然后, 我们重写 MapItem::processUserEvent() 便可接收到自定义事件 BlinkEvent:
virtual void processUserEvent(MapEvent *event) override
{
switch (event->type()) {
case BlinkEvent::BlinkEventType:
{
if (m_point->color() == QColor("#e000a8f3")) {
m_point->setColor(QColor("#e0e00000"));
} else {
m_point->setColor(QColor("#e000a8f3"));
}
} break;
default:
break;
}
}
此时, 我们的处理就是简单的改变一下点的颜色即可(闪烁效果)。

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