QGIS二次开发:鼠标在矢量图层上方悬浮,弹出图层提示

本文介绍如何在QGIS中通过代码实现鼠标悬浮时显示地图提示。通过创建地图提示对象并监听鼠标位置变化,能够在矢量图层上展示特定信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.前言

       某些业务需求,会要求当鼠标在矢量图层上悬浮时,能弹出某些提示。如下为阿拉斯加州矢量图的shp文件在QGIS画布上的显示,当鼠标移动到阿拉斯加州矢量图上方时,会弹出“Alaska”的工具提示:

 怎样用代码实现呢?

2.开发环境说明

  • QGIS 3.26.2
  • Qt 5.14.1
  • Visual Studio 2019

3.代码实现说明

不多说,直接上代码。.h文件如下:

#pragma once

#include <QtWidgets/QMainWindow>
#include "ui_CMyGIS.h"
#include<qgsmaptoolpan.h>
#include"qgsmapcanvas.h"
#include"QgsMapTip.h"
class CMyGIS : public QMainWindow
{
	Q_OBJECT

public:
	CMyGIS(QWidget *parent = Q_NULLPTR);

private:

    // 创建地图提示对象
	void createMapTips();

	// 加载矢量图层
	void addVectorLayer();

	void installSlots();

    // 显示地图提示
	void showMapTip();

private: // slots
	void mouseCoordinateChanged(const QgsPointXY& newCoordinate);
private:


private:
	Ui::CMyGISClass ui;

	// map canvas
	QgsMapCanvas* m_pMapCanvas{ nullptr };
	QList<QgsMapLayer*> m_lstLayers;
	QgsMapToolPan* m_pMapToolPan{nullptr};
	QTimer* m_pMapTipsTimer{ nullptr };
	QgsMapTip* m_pMapTip{ nullptr };
	QgsPointXY m_lastMapPosition; 
};

.cpp文件如下:

#include "CMyGIS.h"
#include"qgsvectorlayer.h"
#include"qgsmaptip.h"

CMyGIS::CMyGIS(QWidget *parent)
	: QMainWindow(parent)
{
	ui.setupUi(this);

	m_pMapCanvas = new QgsMapCanvas(this);
	m_pMapCanvas->setCanvasColor(QColor(255, 255, 255));
	m_pMapCanvas->setVisible(true);
	m_pMapCanvas->enableAntiAliasing(true);

	m_pMapToolPan = new QgsMapToolPan(m_pMapCanvas);
	m_pMapCanvas->setMapTool(m_pMapToolPan);
	setCentralWidget(m_pMapCanvas);

	createMapTips();

	installSlots();

	// 加载矢量图层
	addVectorLayer();
}

void CMyGIS::installSlots()
{
	connect(m_pMapCanvas, &QgsMapCanvas::xyCoordinates, this, &CMyGIS::mouseCoordinateChanged);
}

// 创建地图提示
void CMyGIS::createMapTips()
{
	m_pMapTipsTimer = new QTimer(m_pMapCanvas);
 
	connect(m_pMapTipsTimer, &QTimer::timeout, this, &CMyGIS::showMapTip);

	m_pMapTipsTimer->setInterval(850);
	m_pMapTipsTimer->setSingleShot(true);

	// Create the maptips object
	m_pMapTip = new QgsMapTip();
}

void CMyGIS::showMapTip()
{
	// 鼠标不在地图画布上,直接返回
	if (!m_pMapCanvas->underMouse())
	{
        return;
     }
		
     QPoint myPointerPos = m_pMapCanvas->mouseLastXY();

	 //  Make sure there is an active layer before proceeding
	QgsMapLayer* mypLayer = m_pMapCanvas->currentLayer();
	if (mypLayer)
	{
	   // 仅仅只处理矢量图层
	   if (mypLayer->type() == QgsMapLayerType::VectorLayer)
	   {
		  m_pMapTip->showMapTip(mypLayer, m_lastMapPosition, myPointerPos, m_pMapCanvas);
	   }
	}

}


void CMyGIS::mouseCoordinateChanged(const QgsPointXY& newCoordinate)
{
    m_lastMapPosition = newCoordinate;

	// 鼠标在地图画布上
	if (m_pMapCanvas->underMouse())
	{
		// Clear the maptip (this is done conditionally)
		int interval = qMin(300, m_pMapTipsTimer->interval());

        // 如果之前弹出的提示没消失,先让其消失。
		m_pMapTip->clear(m_pMapCanvas, interval);

        // 启动定时器,以弹出提示
		m_pMapTipsTimer->start();
	}
}

void CMyGIS::addVectorLayer()
{
	QgsVectorLayer* pLayer = new QgsVectorLayer(QString::fromLocal8Bit(R"(D:\GIS测试数据\QGIS-Sample-Data-master\qgis_sample_data\shapefiles\alaska.shp)"), "ogr");
	if ((nullptr == pLayer) || !pLayer->isValid())
	{
		Q_ASSERT(0);
		return;
	}

	m_pMapCanvas->setExtent(pLayer->extent());
	m_lstLayers.append(pLayer);
	m_pMapCanvas->setLayers(m_lstLayers);
	m_pMapCanvas->setCurrentLayer(pLayer);  // 注意:必须设置为当前图层,否则鼠标悬浮不起作用,具体参见showMapTip函数第58行
	m_pMapCanvas->zoomToProjectExtent();
	m_pMapCanvas->refresh();
}




上面加载的alaska.shp包含有QgsFeature(特征),如下,用QGIS官方的QGIS3.26.2.exe打开查看该文件,如下:

按上图表示的步骤操作,可以看到右侧面板有很多 QgsFeature(特征),而上述代码实现的鼠标悬浮弹出的地图提示,其实就是提取的右侧面板的总根名即NAME属性。

注意:

  • 不是每个矢量图层会有QgsFeature(特征),也就是说上图右侧面板可能为空,此时前面代码实现的鼠标悬浮地图提示当前就不存在、不会显示了。
  • 矢量图层如果没有QgsFeature(特征)或有QgsFeature,但不是我们想要的地图提示,可以通过代码加入或修改,从而显示自己想要的地图提示,关于这点如何实现,后期再写博文说明。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值