QStandardItemModel角色控制及QTreeView加入不同的右键菜单
1.概述
QTreeView最长用的一个功能就是作为导航栏,像vs里的项目结构树,word的文档结构图,资源管理器的文档结构,等等都是利用树形结构组织的,在前面已经讲述了Qt中使用标准化项目模型QStandardItemModel对树形控件节点的操作。但有时候,光有节点显示还是不够的,还须要和用户进行交互,如右键点击不同条目会出现不同菜单,这时就须要知道各个节点相应的功能。
2.使用Role对QStandardItem设定值
#define ROLE_MARK_FOLDER Qt::UserRole + 2
#define ROLE_MARK_ITEM Qt::UserRole + 3
#define MARK_PROJECT 1 //这是总项目标记
#define MARK_FOLDER 2 //这是目录标记
#define MARK_ITEM 3 //条目标记
//相应ROLE_MARK_FOLDER,标记folder种类
#define MARK_FOLDER_H 1 //头文件目录标记
#define MARK_FOLDER_CPP 2 //cpp文件目录标记
//相应ROLE_MARK_ITEM标记item种类
#define MARK_ITEM_H 1 //头文件条目
#define MARK_ITEM_CPP 2 //cpp文件条目
void Widget::init()
{
QStandardItemModel* model = new QStandardItemModel(ui->treeView);
model->setHorizontalHeaderLabels(QStringList()<<QStringLiteral("项目"));
//加入项目目录
QStandardItem* root = new QStandardItem(QIcon(":/icon/icon/p.png"),QStringLiteral("项目"));
root->setData(MARK_PROJECT,ROLE_MARK);//首先它是项目中目录
root->setData(MARK_FOLDER,ROLE_MARK_FOLDER);//其次它属于目录
model->appendRow(root);
QStandardItem* folder = new QStandardItem(QIcon(":/icon/icon/h-f.png"),QStringLiteral("头文件"));
folder->setData(MARK_FOLDER,ROLE_MARK);//首先它是目录
folder->setData(MARK_FOLDER_H,ROLE_MARK_FOLDER);//其次它属于头文件目录
root->appendRow(folder);
folder = new QStandardItem(QIcon(":/icon/icon/c-f.png"),QStringLiteral("源文件"));
folder->setData(MARK_FOLDER,ROLE_MARK);//首先它是目录
folder->setData(MARK_FOLDER_CPP,ROLE_MARK_FOLDER);//其次它属于源文件目录
root->appendRow(folder);
ui->treeView->setModel(model);
}
在加入条目时,给一些特别的条目设定标志,如头文件目录,由于它是目录,因此首先给它设定角色为ROLE_MARK的值MARK_FOLDER,其次它在目录中属于头文件目录,因此再给他设定角色为ROLE_MARK_FOLDER的值MARK_FOLDER_H。这时,这个条目就有两个额外的值用于特殊的推断。
QStandardItemModel* Widget::getTreeModel()
{
return qobject_cast<QStandardItemModel*>(ui->treeView->model());
} QList<QStandardItem*> Widget::getRoots()
{
QList<QStandardItem*> roots;
QStandardItemModel* model = getTreeModel();
for(int i=0;i < model->rowCount();++i)
{
roots.append(model->item(i));
}
return roots;
} QStandardItem* Widget::getProjectFolder()
{
QList<QStandardItem*> roots = getRoots();
for(auto i=roots.begin();i!=roots.end();++i){
if((*i)->data(ROLE_MARK) == MARK_PROJECT){
return (*i);
}
}
return nullptr;
} QStandardItem* Widget::getHeaderFolder()
{
QStandardItem* project = getProjectFolder();
if(nullptr == project)
return nullptr;
for(int i=0;i < project->rowCount();++i)
{
QStandardItem* child = project->child(i);
QVariant var = child->data(ROLE_MARK_FOLDER);
if(!var.isValid())
continue;//说明不是ROLE_MARK_FOLDER,有可能是一些项目,相应项目结构树那个xxx.pro就是一个非目录条目
if(MARK_FOLDER_H == var.value<int>())
return child;
}
return nullptr;
} QStandardItem* Widget::getSrcFolder()
{
QStandardItem* project = getProjectFolder();
if(nullptr == project)
return nullptr;
for(int i=0;i < project->rowCount();++i)
{
QStandardItem* child = project->child(i);
QVariant var = child->data(ROLE_MARK_FOLDER);
if(!var.isValid())
continue;//说明不是ROLE_MARK_FOLDER,有可能是一些项目,相应项目结构树那个xxx.pro就是一个非目录条目
if(MARK_FOLDER_CPP == var.value<int>())
return child;
}
return nullptr;
}
void Widget::on_pushButton_clicked()
{
static int s_header_count = 1;
//找到头文件目录
QStandardItem* headerFolder = getHeaderFolder();
if(headerFolder)
{
QStandardItem* item = new QStandardItem(QIcon(":/icon/icon/i.png")
,QStringLiteral("%1.h").arg(s_header_count));
item->setData(MARK_ITEM,ROLE_MARK);//首先标定条目的类型 - 目录、项目、条目…
item->setData(MARK_ITEM_H,ROLE_MARK_ITEM);//再次标定项目的类型
headerFolder->appendRow(item);
++s_header_count;
}
}
首先找到相应的头文件目录,然后再在这问件夹下加入文件。执行效果例如以下图:
3.给树形视图设置右键菜单
void Widget::on_treeView_customContextMenuRequested(const QPoint &pos)
{ }
当然也能够使用代码加入!
#include <QAction>
QMenu* m_itemMenu;
m_projectMenu = new QMenu(this);
m_itemMenu = new QMenu(this); QAction* ac = nullptr;
ac = new QAction(QStringLiteral("构建"),this);
m_projectMenu->addAction(ac); ac = new QAction(QStringLiteral("执行qmake"),this);
m_projectMenu->addAction(ac); ac = new QAction(QStringLiteral("部署"),this);
ac->setEnabled(false);
m_projectMenu->addAction(ac); ac = new QAction(QStringLiteral("执行"),this);
m_projectMenu->addAction(ac); m_projectMenu->addSeparator(); ac = new QAction(QStringLiteral("又一次构建"),this);
m_projectMenu->addAction(ac); ac = new QAction(QStringLiteral("清除"),this);
m_projectMenu->addAction(ac); m_projectMenu->addSeparator(); ac = new QAction(QStringLiteral("加入新文件……"),this);
m_projectMenu->addAction(ac); ac = new QAction(QStringLiteral("余下的省略……"),this);
m_projectMenu->addAction(ac); // ac = new QAction(QStringLiteral("打开文件"),this);
m_itemMenu->addAction(ac);
ac = new QAction(QStringLiteral("在explorer中显示"),this);
m_itemMenu->addAction(ac);
ac = new QAction(QStringLiteral("在此弹出命令提示"),this);
m_itemMenu->addAction(ac); QMenu* itemChildMenu = new QMenu(m_itemMenu);
itemChildMenu->setTitle(QStringLiteral("用…打开"));
ac = new QAction(QStringLiteral("C++编辑器"),this);
itemChildMenu->addAction(ac);
ac = new QAction(QStringLiteral("普通文本编辑器"),this);
itemChildMenu->addAction(ac);
ac = new QAction(QStringLiteral("二进制编辑器"),this);
itemChildMenu->addAction(ac);
ac = new QAction(QStringLiteral("System Editor"),this);
itemChildMenu->addAction(ac); m_itemMenu->addAction(itemChildMenu->menuAction()); ac = new QAction(QStringLiteral("余下省略n条"),this);
m_itemMenu->addAction(ac);
on_treeView_customContextMenuRequested槽函数详细实现代码例如以下:
void Widget::on_treeView_customContextMenuRequested(const QPoint &pos)
{
QModelIndex index = ui->treeView->indexAt(pos);
QVariant var = index.data(ROLE_MARK);
if(var.isValid())
{
if(MARK_PROJECT == var.toInt())
m_projectMenu->exec(QCursor::pos());//弹出右键菜单,菜单位置为光标位置
else if(MARK_ITEM == var.toInt())
m_itemMenu->exec(QCursor::pos());
}
}
4.系统role的使用
void Widget::on_pushButton_3_clicked()
{
QModelIndex index = ui->treeView->currentIndex();
if(!index.isValid())
return;
getTreeModel()->itemFromIndex(index)->setData(QColor(232,209,57,200),Qt::BackgroundRole);
}
效果例如以下:
void Widget::init()
{
QStandardItemModel* model = new QStandardItemModel(ui->treeView);
model->setHorizontalHeaderLabels(QStringList()<<QStringLiteral("项目")); //加入项目目录
QStandardItem* root = new QStandardItem(QIcon(":/icon/icon/p.png"),QStringLiteral("项目"));
root->setData(MARK_PROJECT,ROLE_MARK);//首先它是项目中目录
root->setData(MARK_FOLDER,ROLE_MARK_FOLDER);//其次它属于目录
root->setData(
QStringLiteral("这是关于QStandardItemModel设定角色的教程\n具体介绍见:http://blog.csdn.net/czyt1988/article/details/26018513")
,Qt::ToolTipRole
);
……
}
void Widget::on_pushButton_4_clicked()
{
//涉及到遍历,因此使用回调函数,把遍历须要运行的函数传给封装好的遍历
StandardItemModelEx::ergodicAllItem(getTreeModel()
,std::bind(&Widget::callback_clearColor,this,std::placeholders::_1));
} void Widget::callback_clearColor(QStandardItem* item)
{
item->setData(QVariant(),Qt::BackgroundRole);
}
QStandardItemModel角色控制及QTreeView加入不同的右键菜单的更多相关文章
- QStandardItemModel角色控制及QTreeView添加不同的右键菜单
http://blog.csdn.net/czyt1988/article/details/26018513
- QT5 QTreeView添加右键菜单
C++ QT5学习--QTreeView控件创建右键菜单 QTreeView是QWidget的子类,我们再改写QTreeView类的时候,注意的是继承关系. 1.TreeView.h class Tr ...
- Unity 3D 一个简单的角色控制脚本
之所以写这个脚本,是因为我想起了我还是新手的时候,那时为了一个角色控制脚本百度了半天还是一无所获,因为看不懂啊,都写的太高级了 希望这个脚本能够帮助那些 像曾经的我一样迷失于代码中的新手们能够清晰的理 ...
- Spring Security 整合freemaker 实现简单登录和角色控制
Spring Security 整合freemaker 实现简单登录和角色控制 写这篇文章是因为我做了一个电商网站项目,近期刚加上权限控制.整个过程很简单,在此给大家梳理一下,也算是自己对知识 ...
- [Unity3D]Unity3D游戏开发之角色控制漫谈
各位朋友,大家好.我是秦元培,欢迎大家关注我的博客,我的博客地址blog.csdn.net/qinyuanpei.今天呢,我们来说说Unity3D中的角色控制,这篇文章并非关注于Unity3D中的某项 ...
- ASP.NET Web API编程——接口安全与角色控制
1 API接口验证与授权 JWT JWT定义,它包含三部分:header,payload,signature:每一部分都是使用Base64编码的JSON字符串.之间以句号分隔.signature是”h ...
- ThinkPHP角色控制时的错误
1.Table 'think.think_user' doesn't exist 等的原因是因为'DB_PREFIX' => 'think_', // 数据库表前缀没有配置好,在使用角色控制时 ...
- 【CefSharp】 禁用右键菜单 与 控制弹出窗口的方式(限版本39.0.0.1)
这周没什么时间,一开始就在忙一些CefSharp的事情,Win10的研究就放了下来,CefSharp的资料挺少的,但好在是开源的,可以我们便宜的折腾.因为两个的内容都不多,我就合成一篇文章啦. 这还里 ...
- springboot-28-security(一)用户角色控制
spring security 使用众多的拦截器实现权限控制的, 其核心有2个重要的概念: 认证(Authentication) 和授权 (Authorization)), 认证就是确认用户可以访问当 ...
随机推荐
- Python 关于正负无穷float(‘inf’)的一些用法
Python中可以用如下方式表示正负无穷: float("inf"), float("-inf") 利用 inf 做简单加.乘算术运算仍会得到 inf > ...
- 使用awstats统计分析tengine日志访问量及各种http网站数据
下载awstats最新安装包并解压 cd /usr/local/src wget http://www.awstats.org/files/awstats-7.3.tar.gz tar -zxvf a ...
- c++构造函数谁先执行的问题
看到网上一哥们的帖子 http://blog.csdn.net/maray/article/details/7761709 东西不多就转发了 1 #include <iostream> u ...
- 简单学C——第三天
控制结构(二) 前面我们已经了解到了,控制结构中的判断结构,当然switch语句也是判断语句.不过如果if...else...语句你会了,我相信switch语句你也一定会的,它们的功能都是差不 ...
- scrollView and tableView
As we all know, tableView is the subclass of scrollView, tableView has every properties that scroll ...
- iOSシステム構成の纏め
iOSのアーキテクチャ a) iOSのアーキテクチャは階層化されている最上位レベルでは.iOSはそれが稼働しているハードウェアとアプリケーションの間の仲介役を果たします.アプリケーションが ...
- Arduino从基础到实践第三章练习题
先写在这里,还没经过测试. 1. LED两端往中间移动,到中间后向两边返回. // adr301.ino , , , , , , , , , }; ); ; ; unsigned long chang ...
- nutch-1.7-二次开发-Content中增加编码
1 识别nutch-1.7的编码,完成 以前1.2是在 org.apache.nutch.parse.html.HtmlParser EncodingDetector detector = new E ...
- [BZOJ 3196] 213平衡树 【线段树套set + 树状数组套线段树】
题目链接:BZOJ - 3196 题目分析 区间Kth和区间Rank用树状数组套线段树实现,区间前驱后继用线段树套set实现. 为了节省空间,需要离线,先离散化,这样需要的数组大小可以小一些,可以卡过 ...
- RESTful风格的Web服务框架:Swagger
Swagger与SpringMVC项目整合 为了方便的管理项目中API接口,在网上找了好多关于API接口管理的资料,感觉目前最流行的莫过于Swagger了,功能强大,UI界面漂亮,并且支持在线测试等等 ...