QTreeWidget的右键菜单实现
时光清浅,不觉多年
于 2021-08-26 10:28:35 发布
2815
收藏 25
分类专栏: Qt相关 文章标签: qt 右键菜单
版权
Qt相关
专栏收录该内容
62 篇文章10 订阅
订阅专栏
前言
因为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&)));
1
2
3
4
5
6
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)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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));
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
这样就可以了。
动态类型转换的方式
动态类型转换的方式基本思想同上述差不多,只不过将判定条件从type变为dynamic_cast,代码类似,这里就不写了。
总结
推荐使用type的方式,这种更方便一些。
————————————————
版权声明:本文为优快云博主「时光清浅,不觉多年」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/weixin_43450564/article/details/119925233