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)), 认证就是确认用户可以访问当 ...
随机推荐
- mysql5.7下载与安装,php5.6与mysql5.7整合
Part1 mysql5.7下载 百度“mysql下载”,打开官网 2. 在页面右上角点击,注册/登录 3. 登录后显示下载页面,选择windows 4. 然后选择MySQL Installer ...
- gcc/g++命令认识
gcc & g++是gnu中最主要和最流行的c & c++编译器 . g++用来针对c++的处理命令,以.cpp为后缀,对于c语言后缀名一般为.c.这时候命令换做gcc即可. 下面以T ...
- js插件动态加载js、css解决方案
最近因为工作需要做了一个js自动导入的插件,一开始很天真的以为动态创建个script添加到head中就ok了,试了之后才发现了问题,就是如果同时引入了多个js文件,而且后一个文件中用到了前一个文件中的 ...
- eclipse + maven + jboss 遇到ClassNotFoundException
在使用eclipse + maven + jboss开发过程中,碰到ClassNotFoundException, 原因应该是deployed包中未包含maven的依赖jar. 可以通过如下方法把依赖 ...
- 正则表达式替换img标签src值!!!
方法一: 相关链接:http://bbs.csdn.net/topics/320185735 实例:此实例自己做的时候讲字符串加了alt进行了有关修改 不清楚看上面链接 string test = ...
- jdk各个版本
http://www.cnblogs.com/langtianya/p/3757993.html
- CyclicBarrier的介绍和使用
转自:http://www.itzhai.com/the-introduction-and-use-of-cyclicbarrier.html 类说明: 一个同步辅助类,它允许一组线程互相等待,直到到 ...
- 字符串模式匹配算法——BM、Horspool、Sunday、KMP、KR、AC算法一网打尽
字符串模式匹配算法——BM.Horspool.Sunday.KMP.KR.AC算法一网打尽 本文内容框架: §1 Boyer-Moore算法 §2 Horspool算法 §3 Sunday算法 §4 ...
- Windows多桌面切换(CreateDesktop,SwitchDesktop函数)
unit Unit1; interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms ...
- log4j将日志输出到控制台,文件,邮件
#将日志写到文件 log4j.appender.file=org.apache.log4j.DailyRollingFileAppender log4j.appender.file.File=e\:\ ...