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)), 认证就是确认用户可以访问当 ...
随机推荐
- laravel学习前期遇到的小知识点(1)
1. 目前我用的laravel 5.2.36版本web中间件成为全局中间件(不知道从5.2.26以上就改变了还是怎样,没有深究),也就是之前的版本路由里默认会有一个Route::group的web中间 ...
- mongoengine教程1
mongoengine安装过程,建议先安装好pip,pip是不Python不错的安装包管理器,安装命令:pip install mongoengine. mongoengine是mongodb的pyt ...
- js 中文排序
/** * 比较函数 * @param {Object} param1 要比较的参数1 * @param {Object} param2 要比较的参数2 * @return {Number} 如果pa ...
- linux下date命令实现时间戳与日期的转换
1.查看指定时间的时间戳 查看当前时间 #date +%s 查看指定时间 #date -d 2008-01-01 +%s 1199116800 #date -d 20080101 ...
- iOS: 填充数据表格
功能:创建一个列表并填充 // // main.m // Hello // // Created by lishujun on 14-8-28. // Copyright (c) 2014年 lish ...
- AndroidStudio 更新gradle Error:Failed to complete Gradle execution. Cause: Connection reset
Android Studio 报错:Error:Failed to complete Gradle execution. Cause: Connection reset.把最新可以运行的项目中g ...
- [BZOJ 1733] [Usaco2005 feb] Secret Milking Machine 【二分 + 最大流】
题目链接:BZOJ - 1733 题目分析 直接二分这个最大边的边权,然后用最大流判断是否可以有 T 的流量. 代码 #include <iostream> #include <cs ...
- Nodejs异步
http://cnodejs.org/topic/4f16442ccae1f4aa2700113b http://cnodejs.org/topic/4f16442ccae1f4aa27001123 ...
- 安卓天天练练(十)ListView
ListView不能和ScrollView同时使用,因为它已经包含了滚动支持. 还有个Gallery http://blog.csdn.net/dazlly/article/details/78639 ...
- Dining
poj3281:http://poj.org/problem?id=3281 题意:有n个人,然后有F份食物,D份饮料,然后每一个会有一些喜爱的饮料和食物,问你最多可以使得多少人同时得到一份自己喜爱的 ...