QTreeWidget的右键菜单实现

前言

因为QTreeWidget有明确的父子关系,这个特点使得其可以有着明确的分级关系,对于具有明显从属关系的节点的控制是非常好的。
但是也是由于这个特点,导致如果需要对其进行右键菜单的分级别展示(不同层级的节点具有不同的右键菜单)会有一定的困难。
鉴于此,特意整理了一下对于这个问题的处理方式,具体的逻辑可分为两种:

  • 重写QTreeWidgetItem的方式 —— 通过dynamic_cast来确认级别(也可通过设置type的方式)
  • 设置type的方式 —— 通过type来确定级别

对于不需要特殊存储的节点而言,设置type是一种可以优先考虑的方式,这种方式的特点是简单,代码量较少;但是如果需要存储大量的数据,那么设置type的方式就显得比较繁琐,此时可以通过重写QTreeWidgetItem的方式来自定义节点。

正式操作

首先知晓QTreeWidget中的一个信号:customContextMenuRequested,在使用此信号之前,需要将QTreeWidget的界面属性设置为Qt::CustomContextMenu
在这里插入图片描述
代码如下:

// 设置右键属性
ui.treeWidget->setContextMenuPolicy(Qt::CustomContextMenu);

// 连接信号槽
connect(ui.treeWidget, SIGNAL(customContextMenuRequested(const QPoint &)), 
		this, SLOT(onCustomContextMenuRequested(const QPoint&)));

type的方式

QTreeWidgetItem有一个type属性,这个属性是用来标识不同类型的树节点的,QTreeWidgetItem的构造函数如下所示:
在这里插入图片描述
接下来只需要在构造不同级别的树节点的时候设置不同的类型即可,示例代码如下:

// 首先创建不同级别的item,构造的同时设置type类型。
enum ETestType
{
	ETT_Type_0,
	ETT_Type_1,
	ETT_Type_2,
	ETT_Type_3
};

QTreeWidgetItem *item1 = new QTreeWidgetItem(ETT_Type_0);
QTreeWidgetItem *item2 = new QTreeWidgetItem(ETT_Type_1);
QTreeWidgetItem *item3 = new QTreeWidgetItem(ETT_Type_2);
QTreeWidgetItem *item4 = new QTreeWidgetItem(ETT_Type_3);

item1->addChild(item2);
item2->addChild(item3);
item3->addChild(item4);

ui.treeWidget->addTopLevelItem(item1)
void onCustomContextMenuRequested(const QPoint & pt)
{
	auto itemList = ui.treeWidget->selectedItems();
	if (itemList.size() < 1 || nullptr == itemList.first())
	{
		return;
	}

	int type = itemList.first()->type();
	QMenu menu(ui.treeWidget);

	if (ETT_Type_0== type)
	{
		menu.addAction(action0_1);
		menu.addAction(action0_2);
		menu.addAction(action0_3);
	}
	else if (ETT_Type_1 == type)
	{
		menu.addAction(action1_1);
		menu.addAction(action1_2);
		menu.addAction(action1_3);
	}
	else if (ETT_Type_2 == type)
	{
		menu.addAction(action2_1);
		menu.addAction(action2_2);
		menu.addAction(action2_3);
	}
	else if (ETT_Type_3 == type)
	{
		menu.addAction(action3_1);
		menu.addAction(action3_2);
		menu.addAction(action3_3);
	}
	else
	{
		return;
	}

	// 修改显示点为全局位置
	menu.exec(ui.treeWidget->mapToGlobal(pt));
}

这样就可以了。

动态类型转换的方式

动态类型转换的方式基本思想同上述差不多,只不过将判定条件从type变为dynamic_cast,代码类似,这里就不写了。

总结

推荐使用type的方式,这种更方便一些。

  • 4
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以通过以下步骤为 `QTreeWidget` 添加右键菜单: 1. 创建右键菜单 `QMenu` 对象 ```python menu = QMenu(self) ``` 2. 向菜单中添加菜单项 `QAction` 对象 ```python action = QAction("菜单项", self) menu.addAction(action) ``` 3. 连接菜单项的 `triggered` 信号到槽函数 ```python action.triggered.connect(self.on_menu_item_clicked) ``` 4. 在 `QTreeWidget` 上注册右键菜单,并在鼠标右键按下事件中显示菜单 ```python def contextMenuEvent(self, event): if self.itemAt(event.pos()) is not None: menu.exec_(self.mapToGlobal(event.pos())) ``` 完整代码示例: ```python from PyQt5.QtWidgets import QWidget, QTreeWidget, QTreeWidgetItem, QMenu, QAction class MyWidget(QWidget): def __init__(self): super().__init__() self.tree_widget = QTreeWidget(self) self.tree_widget.setHeaderLabels(["Name", "Value"]) # 添加根节点 root = QTreeWidgetItem(self.tree_widget, ["Root", ""]) # 添加子节点 child1 = QTreeWidgetItem(root, ["Child1", "Value1"]) child2 = QTreeWidgetItem(root, ["Child2", "Value2"]) # 注册右键菜单 self.tree_widget.setContextMenuPolicy(Qt.CustomContextMenu) self.tree_widget.customContextMenuRequested.connect(self.show_context_menu) def show_context_menu(self, pos): item = self.tree_widget.itemAt(pos) if item is not None: menu = QMenu(self) action = QAction("菜单项", self) action.triggered.connect(self.on_menu_item_clicked) menu.addAction(action) menu.exec_(self.mapToGlobal(pos)) def on_menu_item_clicked(self): print("菜单项被点击了") ``` 在上述示例中,我们为 `QTreeWidget` 的根节点和子节点添加了右键菜单,并在菜单项被点击时打印一条消息。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值