QGIS二次开发3: 图层目录右键菜单项、添加图层组

在上一篇文章中,实现了图层列表。本篇文章,我们讲解如何在图层列表上,点击图层右键出现菜单项,并添加相应的功能。计划实现如下几点功能:

1.添加图层组、展开/折叠图层组;

2.图层目录右键菜单项;

3.zoom to layer、删除图层图层组、重命名图层图层组、显示要素个数。

接着上一篇文章,更新了初始化图层列表函数的内容,整体代码如下,接下来会依次讲解里面的内容。

	//新建图层树形控件
	mLayerTreeView = new QgsLayerTreeView(this);
	mLayerTreeView->setObjectName(QStringLiteral("theLayerTreeView"));

	//创建QgsLayerTreeModel 实例,并允许用户通过点选复选框手动隐藏/显示图层
	QgsLayerTreeModel* model = new QgsLayerTreeModel(QgsProject::instance()->layerTreeRoot(), this);
	model->setFlag(QgsLayerTreeModel::AllowNodeChangeVisibility);
	model->setFlag(QgsLayerTreeModel::AllowNodeReorder);
	model->setFlag(QgsLayerTreeModel::AllowNodeRename);
	model->setFlag(QgsLayerTreeModel::ShowLegendAsTree);
	model->setFlag(QgsLayerTreeModel::UseEmbeddedWidgets);
	model->setFlag(QgsLayerTreeModel::UseTextFormatting);
	model->setAutoCollapseLegendNodes(10);

	//将View视图与Model数据绑定
	mLayerTreeView->setModel(model);

	//将工程实例中的图层根节点与画布绑定,实现与地图画布控件的数据交互
	mLayerTreeCanvasBridge = new QgsLayerTreeMapCanvasBridge(QgsProject::instance()->layerTreeRoot(), mMapCanvas, this);

	//添加图层组
	QAction* addGroup = new QAction(tr("Add Group"), this);
	addGroup->setIcon(createIcon(Add_Group));
	addGroup->setToolTip(tr("Add Group"));
	connect(addGroup, &QAction::triggered, mLayerTreeView->defaultActions(), &QgsLayerTreeViewDefaultActions::addGroup);
	//展开所有图层组
	QAction* actionExpandAll = new QAction(tr("Expand All"), this);
	actionExpandAll->setIcon(createIcon(Expand_All));
	actionExpandAll->setToolTip(tr("Expand All"));
	connect(actionExpandAll, &QAction::triggered, mLayerTreeView, &QgsLayerTreeView::expandAllNodes);
	//折叠所有图层组
	QAction* actionCollapseAll = new QAction(tr("Collapse All"), this);
	actionCollapseAll->setIcon(createIcon(Collapse_All));
	actionCollapseAll->setToolTip(tr("Collapse All"));
	connect(actionCollapseAll, &QAction::triggered, mLayerTreeView, &QgsLayerTreeView::collapseAllNodes);

	QToolBar* toolbar = new QToolBar(this);
	toolbar->setIconSize(QSize(16, 16));
	toolbar->addAction(addGroup);
	toolbar->addAction(actionExpandAll);
	toolbar->addAction(actionCollapseAll);

	QVBoxLayout* vboxLayout = new QVBoxLayout;
	vboxLayout->setContentsMargins(0, 0, 0, 0);
	vboxLayout->setSpacing(0);
	vboxLayout->addWidget(toolbar);
	vboxLayout->addWidget(mLayerTreeView);

	QWidget* w = new QWidget;
	w->setLayout(vboxLayout);

	//设置点击右键出现菜单项
	mLayerTreeView->setMenuProvider(new QtGisLayerTreeViewMenuProvider(mLayerTreeView, mMapCanvas));

	//将View添加到左侧的Dock控件中展示
	mLayerMapDock->setWidget(w);

一、添加图层组、展开/折叠图层组

1.首先新建添加图层组、展开/折叠图层组三个QAction。

分别将这三个QAction的点击动作与槽函数绑定。

在mLayerTreeView->defaultActions()所有默认action中,实现了addGroup方法,所以这里的receiver是mLayerTreeView->defaultActions()。

	connect(addGroup, &QAction::triggered, mLayerTreeView->defaultActions(), &QgsLayerTreeViewDefaultActions::addGroup);

而展开/折叠的图层组是由QgsLayerTreeView实现的,所以这里的receiver是mLayerTreeView。

	connect(actionExpandAll, &QAction::triggered, mLayerTreeView, &QgsLayerTreeView::expandAllNodes);
	connect(actionCollapseAll, &QAction::triggered, mLayerTreeView, &QgsLayerTreeView::collapseAllNodes);

 2.将QAction添加到QToolBar中,并将QToolBar与图层树控件mLayerTreeView一起添加到左侧Dock控件中。

二、图层目录右键菜单项

为图层目录添加右键菜单项,是由以下这句话实现:

	//设置点击右键出现菜单项
	mLayerTreeView->setMenuProvider(new QtGisLayerTreeViewMenuProvider(mLayerTreeView, mMapCanvas));

我们可以看QGIS源码中对于setMenuProvider函数的定义,说明函数里面参数是一个QgsLayerTreeViewMenuProvider 类的实例。

    //! Sets provider for context menu. Takes ownership of the instance
    void setMenuProvider( QgsLayerTreeViewMenuProvider *menuProvider SIP_TRANSFER );

再看QgsLayerTreeViewMenuProvider类的定义,其中createContextMenu函数就是创建菜单项的函数,我们只需要在自定义的函数中继承QgsLayerTreeViewMenuProvider类,并实现createContextMenu函数即可。

class GUI_EXPORT QgsLayerTreeViewMenuProvider
{
  public:
    virtual ~QgsLayerTreeViewMenuProvider() = default;

    //! Returns a newly created menu instance (or NULLPTR on error)
    virtual QMenu *createContextMenu() = 0 SIP_FACTORY;
};

1.添加自定义类

自定义类的头文件实现如下,其中mMapCanvas和mView用于存储从主类传过来的地图画布和图层列表。

#include "qgslayertreeview.h"

class QgsMapCanvas;

class QtGisLayerTreeViewMenuProvider :
    public QgsLayerTreeViewMenuProvider
{
public:
    QtGisLayerTreeViewMenuProvider(QgsLayerTreeView* layerTreeView, QgsMapCanvas* mapCanvas);

    ~QtGisLayerTreeViewMenuProvider();

    virtual QMenu* createContextMenu() override;

private:
    QgsMapCanvas* mMapCanvas;

    QgsLayerTreeView* mView;
};

在.cpp文件的构造函数中,给mMapCanvas和mView赋值。

QtGisLayerTreeViewMenuProvider::QtGisLayerTreeViewMenuProvider(QgsLayerTreeView* layerTreeView, QgsMapCanvas* mapCanvas)
	:QgsLayerTreeViewMenuProvider()
	, mMapCanvas(mapCanvas)
	, mView(layerTreeView)
{
}

2.实现createContextMenu函数,添加菜单项。

createContextMenu函数的整体代码如下:

QMenu* QtGisLayerTreeViewMenuProvider::createContextMenu()
{
	QMenu* menu = new QMenu;
	QModelIndex index = mView->currentIndex();
	if (!index.isValid()) return nullptr;
	QgsLayerTreeNode* node = mView->index2node(index);
	if (QgsLayerTree::isGroup(node)) {
		menu->addAction(mView->defaultActions()->actionRemoveGroupOrLayer(menu));
		menu->addAction(mView->defaultActions()->actionRenameGroupOrLayer(menu));
	}
	else if(QgsLayerTree::isLayer(node)){
		QgsMapLayer* layer = QgsLayerTree::toLayer(node)->layer();
		if (layer) {
			menu->addAction(mView->defaultActions()->actionZoomToLayer(mMapCanvas,menu));
			menu->addAction(mView->defaultActions()->actionRemoveGroupOrLayer(menu));
			menu->addAction(mView->defaultActions()->actionRenameGroupOrLayer(menu));
		}
		QgsVectorLayer* vLayer = qobject_cast<QgsVectorLayer*>(layer);
		if (vLayer) {
			menu->addAction(mView->defaultActions()->actionShowFeatureCount(menu));
		}
	}

	return menu;
}

接下来依次讲解createContextMenu函数中的内容。

首先获取图层列表中的当前图层节点。

	QModelIndex index = mView->currentIndex();
	if (!index.isValid()) return nullptr;
	QgsLayerTreeNode* node = mView->index2node(index);

如果该节点是图层组,则向菜单menu中添加删除/重命名图层组的功能

	if (QgsLayerTree::isGroup(node)) {
		menu->addAction(mView->defaultActions()->actionRemoveGroupOrLayer(menu));
		menu->addAction(mView->defaultActions()->actionRenameGroupOrLayer(menu));
	}

如果是图层,且是矢量图层则添加显示要素个数的功能。

        QgsVectorLayer* vLayer = qobject_cast<QgsVectorLayer*>(layer);
		if (vLayer) {
			menu->addAction(mView->defaultActions()->actionShowFeatureCount(menu));
		}

3.其他功能实现

如果还想实现其他功能,可以参考QgsLayerTreeViewDefaultActions这个类中,提供的功能,按照上面的方式提供即可;如果需要实现一些自定义的功能,则自己定义QAction,添加到menu中并实现相应的功能即可。

最后实现的效果如下:

项目git地址:https://github.com/guoqiongGit/QtGisDemo

欢迎下载共同交流、学习。 

  • 7
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值