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


    1.前言

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

     怎样用代码实现呢?

    2.开发环境说明

    • QGIS 3.26.2
    • Qt 5.14.1
    • Visual Studio 2019

    3.代码实现说明

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

    1. #pragma once
    2. #include
    3. #include "ui_CMyGIS.h"
    4. #include
    5. #include"qgsmapcanvas.h"
    6. #include"QgsMapTip.h"
    7. class CMyGIS : public QMainWindow
    8. {
    9. Q_OBJECT
    10. public:
    11. CMyGIS(QWidget *parent = Q_NULLPTR);
    12. private:
    13. // 创建地图提示对象
    14. void createMapTips();
    15. // 加载矢量图层
    16. void addVectorLayer();
    17. void installSlots();
    18. // 显示地图提示
    19. void showMapTip();
    20. private: // slots
    21. void mouseCoordinateChanged(const QgsPointXY& newCoordinate);
    22. private:
    23. private:
    24. Ui::CMyGISClass ui;
    25. // map canvas
    26. QgsMapCanvas* m_pMapCanvas{ nullptr };
    27. QList m_lstLayers;
    28. QgsMapToolPan* m_pMapToolPan{nullptr};
    29. QTimer* m_pMapTipsTimer{ nullptr };
    30. QgsMapTip* m_pMapTip{ nullptr };
    31. QgsPointXY m_lastMapPosition;
    32. };

    .cpp文件如下:

    1. #include "CMyGIS.h"
    2. #include"qgsvectorlayer.h"
    3. #include"qgsmaptip.h"
    4. CMyGIS::CMyGIS(QWidget *parent)
    5. : QMainWindow(parent)
    6. {
    7. ui.setupUi(this);
    8. m_pMapCanvas = new QgsMapCanvas(this);
    9. m_pMapCanvas->setCanvasColor(QColor(255, 255, 255));
    10. m_pMapCanvas->setVisible(true);
    11. m_pMapCanvas->enableAntiAliasing(true);
    12. m_pMapToolPan = new QgsMapToolPan(m_pMapCanvas);
    13. m_pMapCanvas->setMapTool(m_pMapToolPan);
    14. setCentralWidget(m_pMapCanvas);
    15. createMapTips();
    16. installSlots();
    17. // 加载矢量图层
    18. addVectorLayer();
    19. }
    20. void CMyGIS::installSlots()
    21. {
    22. connect(m_pMapCanvas, &QgsMapCanvas::xyCoordinates, this, &CMyGIS::mouseCoordinateChanged);
    23. }
    24. // 创建地图提示
    25. void CMyGIS::createMapTips()
    26. {
    27. m_pMapTipsTimer = new QTimer(m_pMapCanvas);
    28. connect(m_pMapTipsTimer, &QTimer::timeout, this, &CMyGIS::showMapTip);
    29. m_pMapTipsTimer->setInterval(850);
    30. m_pMapTipsTimer->setSingleShot(true);
    31. // Create the maptips object
    32. m_pMapTip = new QgsMapTip();
    33. }
    34. void CMyGIS::showMapTip()
    35. {
    36. // 鼠标不在地图画布上,直接返回
    37. if (!m_pMapCanvas->underMouse())
    38. {
    39. return;
    40. }
    41. QPoint myPointerPos = m_pMapCanvas->mouseLastXY();
    42. // Make sure there is an active layer before proceeding
    43. QgsMapLayer* mypLayer = m_pMapCanvas->currentLayer();
    44. if (mypLayer)
    45. {
    46. // 仅仅只处理矢量图层
    47. if (mypLayer->type() == QgsMapLayerType::VectorLayer)
    48. {
    49. m_pMapTip->showMapTip(mypLayer, m_lastMapPosition, myPointerPos, m_pMapCanvas);
    50. }
    51. }
    52. }
    53. void CMyGIS::mouseCoordinateChanged(const QgsPointXY& newCoordinate)
    54. {
    55. m_lastMapPosition = newCoordinate;
    56. // 鼠标在地图画布上
    57. if (m_pMapCanvas->underMouse())
    58. {
    59. // Clear the maptip (this is done conditionally)
    60. int interval = qMin(300, m_pMapTipsTimer->interval());
    61. // 如果之前弹出的提示没消失,先让其消失。
    62. m_pMapTip->clear(m_pMapCanvas, interval);
    63. // 启动定时器,以弹出提示
    64. m_pMapTipsTimer->start();
    65. }
    66. }
    67. void CMyGIS::addVectorLayer()
    68. {
    69. QgsVectorLayer* pLayer = new QgsVectorLayer(QString::fromLocal8Bit(R"(D:\GIS测试数据\QGIS-Sample-Data-master\qgis_sample_data\shapefiles\alaska.shp)"), "ogr");
    70. if ((nullptr == pLayer) || !pLayer->isValid())
    71. {
    72. Q_ASSERT(0);
    73. return;
    74. }
    75. m_pMapCanvas->setExtent(pLayer->extent());
    76. m_lstLayers.append(pLayer);
    77. m_pMapCanvas->setLayers(m_lstLayers);
    78. m_pMapCanvas->setCurrentLayer(pLayer); // 注意:必须设置为当前图层,否则鼠标悬浮不起作用,具体参见showMapTip函数第58行
    79. m_pMapCanvas->zoomToProjectExtent();
    80. m_pMapCanvas->refresh();
    81. }

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

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

    注意:

    • 不是每个矢量图层会有QgsFeature(特征),也就是说上图右侧面板可能为空,此时前面代码实现的鼠标悬浮地图提示当前就不存在、不会显示了。
    • 矢量图层如果没有QgsFeature(特征)或有QgsFeature,但不是我们想要的地图提示,可以通过代码加入或修改,从而显示自己想要的地图提示,关于这点如何实现,后期再写博文说明。
  • 相关阅读:
    2023考研常识之全国考研初试成绩基本分区要求是如何界定的?
    毛里智慧小学宿舍楼工程量清单编制
    数据产品读书笔记——认识数据产品经理
    jenkins自动化部署安装
    Sui主网升级至V1.10.1版本
    【Dive into Deep Learning / 动手学深度学习】第十章 - 第二节:注意力汇聚:Nadaraya-Watson 核回归
    (十五)admin-boot项目之使用undertow来替代tomcat容器
    【自然语言处理(NLP)】文本数据处理实践
    JavaScript中的原型和原型链
    2022系统分析师下午卷(案例分析)
  • 原文地址:https://blog.csdn.net/danshiming/article/details/127656445