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)), 认证就是确认用户可以访问当 ...
随机推荐
- swift从0加到1000(不包括1000)的五种写法
用了while, do...while, for in, for in ... { temp += i i++ } println(temp) do { temp2 += j j++ } ) prin ...
- directUI
MFC界面开发中,习惯了使用控件,亦或者是自绘制控件来美化界面,但操作起来繁琐,还不太美观.DirectUI的出现,对于界面开发,给了我们一个新的选择,目前很多公司使用了该技术对其产品进行了美化,效果 ...
- GHOST备份
整理日: 2015年2月16日 GHOST Disk2GHO STEP01 STEP02 STEP03 STEP04 STEP05 STEP06 STEP07 STEP08 STEP09 STEP10
- C连接MySQL数据库开发之Xcode环境配置及测试
一.开发环境 Mac OS X 10.9.2 64位.Xcode5.1.MySQL5.5.37 64位 MySQL安装目录为:/usr/local/mysql 二.配置xcode连接mysql的编译选 ...
- bzoj 1014: [JSOI2008]火星人prefix hash && splay
1014: [JSOI2008]火星人prefix Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3154 Solved: 948[Submit][ ...
- bzoj 2733: [HNOI2012]永无乡 离线+主席树
2733: [HNOI2012]永无乡 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1167 Solved: 607[Submit][Status ...
- Netty实现服务端客户端长连接通讯及心跳检测
通过netty实现服务端与客户端的长连接通讯,及心跳检测. 基本思路:netty服务端通过一个Map保存所有连接上来的客户端SocketChannel,客户端的Id作为Map的key.每 ...
- HBase学习笔记之HFile格式
主要看Roger的文档,这里作为文档的补充 HFile的格式-HFile的基本结构 Trailer通过指针找到Meta index.Data index.File info. Meta index保存 ...
- apple ID的重要性
当手机丢失时,您可以将对应的产品码提供给运营商,提高找回丢失手机的可能性. 2.去App store下载“查找我的iPhone(Find My iPhone)”,立刻安上,用你的app ...
- 移植lrzsz串口文件传输工具到mini2440
1.下载源码2.解压源码 tar -xzf lrzsz-0.12.20.tar.gz 3.检查配置 ./configure 4.修改Makefile 有三个Makefile需要修改,分别是lrzsz- ...