QTreeView的使用总结1
来源:互联网 发布:windows to go可以 编辑:程序博客网 时间:2024/05/21 03:25
一、概述
Qt中 treeview的典型使用方法是model/view。这里不介绍model、view、delegate的工作方式。
model 、delegate与treeview的关联过程如下:
ui.treeView->setModel( pModel );ui.treeView->setItemDelegate( pDelegate );
二、设置TreeView的头部信息
1、设置表头
方法一:void QStandardItemModel::setHorizontalHeaderLabels( const QStringList & labels );
参数labels指定一个QStringList对象,该对象中的每个字符串对应一个列的名字。
方法二:void QStandardItemModel::setHorizontalHeaderItem(int column, QStandardItem * item);
参数 column指定列的索引,item指定列的内容
例子:分别使用上述两种方法设置TreeView头部信息
方法一:
QStringList ColumnStringList;ColumnStringList << QStringLiteral("车库") << QStringLiteral("信息");model->setHorizontalHeaderLabels( QStringList() << QStringLiteral("车库")<< QStringLiteral("信息") );QStandardItem* pColumnItem = model->horizontalHeaderItem(0);pColumnItem->setIcon( QIcon(":/TreeView_T/Resources/qt-logo.png") );pColumnItem->setToolTip(QStringLiteral("这是第一列") );pColumnItem = model->horizontalHeaderItem(1);pColumnItem->setIcon(QIcon(":/TreeView_T/Resources/qt-logo.png") );pColumnItem->setToolTip(QStringLiteral("这是第二列"));方法二:
QStandardItem* pItem = new QStandardItem( QIcon(":/TreeView_T/Resources/qt-logo.png"), QStringLiteral("车库"));pItem->setToolTip( QStringLiteral("这是第一列"));QStandardItem* pItem1 = new QStandardItem( QIcon(":/TreeView_T/Resources/qt-logo.png"), QStringLiteral("信息") );pItem1->setToolTip( QStringLiteral("这是第二列"));model->setHorizontalHeaderItem( 0, pItem);model->setHorizontalHeaderItem( 1, pItem1);
2、隐藏表头
通过QTreeView中的 header()->hide(),可以隐藏表头。
三、填充行与列
(1)、可以在行头部添加图标
例子:
QMap<QString, QIcon> m_IconMap;//存放公共图标QMap<QString, QIcon> m_CarportIconMap; //车库公共图标//初始化图标库m_CarportIconMap[QStringLiteral("Port1")] = QIcon(QStringLiteral(":/cars1/Resources/cars1/3942000.ico"));m_CarportIconMap[QStringLiteral("Port2")] = QIcon(QStringLiteral(":/cars1/Resources/cars1/3942001.ico"));m_CarportIconMap[QStringLiteral("Port3")] = QIcon(QStringLiteral(":/cars1/Resources/cars1/3942002.ico"));m_CarportIconMap[QStringLiteral("Port4")] = QIcon(QStringLiteral(":/cars1/Resources/cars1/3942003.ico"));m_CarportIconMap[QStringLiteral("Port5")] = QIcon(QStringLiteral(":/cars1/Resources/cars1/3942004.ico"));m_IconMap[QStringLiteral("Audi")] = QIcon( QStringLiteral(":/cars_logo/Resources/cars_logo/audi.ico") );m_IconMap[QStringLiteral("Bmw")] = QIcon( QStringLiteral(":/cars_logo/Resources/cars_logo/bmw.ico") );m_IconMap[QStringLiteral("Buick")] = QIcon( QStringLiteral(":/cars_logo/Resources/cars_logo/Buick.ico") );m_IconMap[QStringLiteral("Cadillac")] = QIcon( QStringLiteral(":/cars_logo/Resources/cars_logo/cadillac.ico") );m_IconMap[QStringLiteral("Ferrari")] = QIcon( QStringLiteral(":/cars_logo/Resources/cars_logo/ferrari.ico") );m_IconMap[QStringLiteral("Ford")] = QIcon( QStringLiteral(":/cars_logo/Resources/cars_logo/ford.ico") );m_IconMap[QStringLiteral("Hyundai")] = QIcon( QStringLiteral(":/cars_logo/Resources/cars_logo/hyundai.ico") );m_IconMap[QStringLiteral("Lexus")] = QIcon( QStringLiteral(":/cars_logo/Resources/cars_logo/lexus.ico") );m_IconMap[QStringLiteral("Mazda")] = QIcon( QStringLiteral(":/cars_logo/Resources/cars_logo/mazda.ico") );m_IconMap[QStringLiteral("Mercedesbenz")] = QIcon( QStringLiteral(":/cars_logo/Resources/cars_logo/mercedesbenz.ico") );m_IconMap[QStringLiteral("Nissan")] = QIcon( QStringLiteral(":/cars_logo/Resources/cars_logo/nissan.ico") );m_IconMap[QStringLiteral("Toyota")] = QIcon( QStringLiteral(":/cars_logo/Resources/cars_logo/toyota.ico") );m_IconMap[QStringLiteral("Volkswagen")] = QIcon( QStringLiteral(":/cars_logo/Resources/cars_logo/Volkswagen.ico") );QStandardItem* pStandardItem = NULL;QStandardItem* pStandardChildItem = NULL;int i = 0;QMap<QString, QIcon>::const_iterator it1 = m_CarportIconMap.constBegin();for (QMap<QString, QIcon>::const_iterator it = m_IconMap.constBegin(); it != m_IconMap.constEnd(); ++it){if (i % 3 == 0){pStandardItem = new QStandardItem((it1 + (i / 3)).value(), (it1 + (i / 3)).key());model->appendRow(pStandardItem);}pStandardChildItem = new QStandardItem( it.value(), it.key());pStandardItem->appendRow( pStandardChildItem );pStandardItem->setChild( pStandardChildItem->row(),1, new QStandardItem( QString("this is %1").arg( it.key()) ));++i;}效果如下:
(2)、可以在行头添加单选框
使用QStandardItem时与checkbox相关的几个函数:
void QStandardItem::setCheckable(bool checkable); //设置Item是否有复选框功能
void QStandardItem::setCheckState(Qt::CheckState state); //设置Item的复选状态
Qt::CheckState有三种状态:Qt::Unchecked :未选中状态、Qt::PartiallyChecked:部分选中状态(层次模型中的子项有一部分处于选中状态)、Qt::Checked:选中状态
void QStandardItem::setTristate(bool tristate); //设置Item是否是三态的(Qt::Unchecked、Qt::PartiallyChecked、Qt::Checked)
Qt::CheckState QStandardItem::checkState() const ; //返回Item的复选状态
bool QStandardItem::isCheckable() const ; //判断Item是否是可复选的
bool QStandardItem::isTristate() const ; //判断Item是否是三态的
例子:
QStandardItem* pStandardItem = NULL;QStandardItem* pStandardChildItem = NULL;int i = 0;QMap<QString, QIcon>::const_iterator it1 = m_CarportIconMap.constBegin();for (QMap<QString, QIcon>::const_iterator it = m_IconMap.constBegin(); it != m_IconMap.constEnd(); ++it){if (i % 3 == 0){pStandardItem = new QStandardItem((it1 + (i / 3)).value(), (it1 + (i / 3)).key());//设置Item为三态pStandardItem->setTristate( true );//设置Item为部分选中状态pStandardItem->setCheckState( Qt::PartiallyChecked );model->appendRow(pStandardItem);}pStandardChildItem = new QStandardItem( it.value(), it.key());//设置Item具有单选能力pStandardChildItem->setCheckable( true );//设置Item不具有三态pStandardChildItem->setTristate( false );//设置Item为选中状态pStandardChildItem->setCheckState( /*Qt::PartiallyChecked*/ Qt::Checked );pStandardItem->appendRow( pStandardChildItem );pStandardItem->setChild( pStandardChildItem->row(),1, new QStandardItem( QString("this is %1").arg( it.key()) ));++i;}效果如下:
(3)三态复选框的智能关联(如果子项全选,父级也需要全选,如果子项部分选,父级就不完全选)
/*QTreeView在QStandardItemModel设置复选框后,并不是按照规则的,需要通过代码设置三态复选框主要体现在树形控件里,如果子项目全选,父级需要全选,如果子项目部分选择,父级就是不完全选*//*item checkbox单击响应函数*/void MyDelegate::treeItem_CheckChanged(QStandardItem* item){if (item == nullptr){return;}if (item->isCheckable() ){//如果item是存在复选框的,那么就进行下面的操作Qt::CheckState state = item->checkState(); //获取当前的选择状态if (item->isTristate()){//如果item是三态的,说明可以对子目录进行全选和全不选的设置if (state != Qt::PartiallyChecked){//当前是选中状态,需要对其子项目设置为全选treeItem_CheckAllChild(item, state == Qt::Checked ? true : false);}}else{//说明是两态的,两态会对父级的三态有影响//判断兄弟节点的情况treeItem_CheckChildChanged( item );}}} //// \brief 递归设置所有的子项目为全选或全不选状态// \param item 当前项目// \param check true时为全选,false时全不选//void MyDelegate::treeItem_CheckAllChild(QStandardItem* item, bool check){if (item == nullptr){return;}int rowCount = item->rowCount();for (int i = 0; i < rowCount; ++i ){QStandardItem* childItems = item->child( i );treeItem_checkAllChild_recursion( childItems, check);}if (item->isCheckable()){item->setCheckState( check ? Qt::Checked : Qt::Unchecked);}}void MyDelegate::treeItem_checkAllChild_recursion(QStandardItem* item, bool check){if (item == nullptr){return;}int rowCount = item->rowCount();for (int i = 0; i < rowCount; ++i){QStandardItem* childItems = item->child( i );treeItem_checkAllChild_recursion( childItems, check);}if (item->isCheckable()){item->setCheckState( check ? Qt::Checked : Qt::Unchecked );}}//// \brief 根据子节点的改变,更改父节点的选择情况// \param item////此函数也是一个递归函数,首先要判断的是父级是否到达顶层//,到达底层作为递归的结束,然后通过函数checkSibling判断当前的兄弟节点的具体情况//void MyDelegate::treeItem_CheckChildChanged(QStandardItem* item){if (nullptr == item){return;}Qt::CheckState siblingState = checkSibling( item );QStandardItem* parentItem = item->parent();if (nullptr == parentItem){return;}if (Qt::PartiallyChecked == siblingState){if (parentItem->isCheckable() && parentItem->isTristate())parentItem->setCheckState( Qt::PartiallyChecked );}else if (Qt::Checked == siblingState){if (parentItem->isCheckable())parentItem->setCheckState( Qt::Checked);}else{if (parentItem->isCheckable())parentItem->setCheckState( Qt::Unchecked );}treeItem_CheckChildChanged( parentItem );}//// \brief 测量兄弟节点的情况,如果都选中返回Qt::Checked,都不选中Qt::Unchecked, // \不完全选中返回Qt::PartiallyChecked// \param item// \return Qt::CheckState MyDelegate::checkSibling(QStandardItem* item){//先通过父节点获取兄弟节点QStandardItem* parent = item->parent();if (nullptr == parent){return item->checkState();}int brotherCount = parent->rowCount();int checkedCount(0), unCheckedCount( 0 );Qt::CheckState state;for (int i = 0; i < brotherCount; ++i){QStandardItem* siblingItem = parent->child( i );state = siblingItem->checkState();if (Qt::PartiallyChecked == state){return Qt::PartiallyChecked;}else if (Qt::Unchecked == state){++unCheckedCount;}else{++checkedCount;}if (checkedCount > 0 && unCheckedCount > 0){return Qt::PartiallyChecked;}}if (unCheckedCount > 0){return Qt::Unchecked;}return Qt::Checked;}
四、QStandardItemModel的角色控制
<一>、自定义角色的使用
在MFC中,树形控件CTreeCtrl是通过SetItemData函数来对节点设置一个指针的值,这个值可以是个指针、DWORD值、自定义的标志或者自定义类型的指针。Qt的TreeView比MFC的CTreeCtrl封装的更好,其功能也更强大,以至于可以给每个节点设定非常非常多的值(只要内存足够)。QTreeView只负责显示渲染,数据都有Model来负责管理。我们可以使用setData函数来为节点设置数据。
setData函数在Model和Item中都有,功能都一样。QStandardItemModel中setData函数的定义:
virtual bool setData( const QModelIndex & index, const QVarient & value, int role = Qt::EditRole);
QStandardItem中setData的定义是:
virtual void setData( const QVaritant & value, int role = Qt::UserRole + 1 );
参数:value:是要设置的值, role是一个int型数据,Qt中把这个称为role角色,实际就是对设定值的标定,因为item可以设置许多值,这就需要一个用以区分的标志,这个区分标志就叫角色。Qt已经把经常用到的角色内容定义好了,我们可以自定义角色标志,但不要和定义好的那些标志冲突,否则会不起作用。如果显示文字就用Qt::DisplayRole,要告诉QTreeView需要改变背景颜色,就标定Qt::BackgroundRole,要改变字体就标定Qt::FontRole等等。从中可以看出,role就是一个标示,用来标定存放在item李淼的值集体用于什么功能,系统默认的role参看Qt::ItemDataRole枚举。自定义的Role,就从Qt::UserRole开始往上加。
例子:
定义用户自定义的role:
#define ROLE_MARK_TYPE Qt::UserRole + 100#define MARK_FOLDER 1#define MARK_ITEM 2为Item设置数据
QStandardItem* pStandardItem = NULL;QStandardItem* pStandardChildItem = NULL;int i = 0;QMap<QString, QIcon>::const_iterator it1 = m_CarportIconMap.constBegin();for (QMap<QString, QIcon>::const_iterator it = m_IconMap.constBegin(); it != m_IconMap.constEnd(); ++it){if (i % 3 == 0){pStandardItem = new QStandardItem((it1 + (i / 3)).value(), (it1 + (i / 3)).key());pStandardItem->setCheckable( true );//设置Item为三态pStandardItem->setTristate( true );//为Item设置自定义rolepStandardItem->setData( MARK_FOLDER, ROLE_MARK_TYPE ); //标记该item为文件夹model->appendRow(pStandardItem);}pStandardChildItem = new QStandardItem( it.value(), it.key());//设置Item具有单选能力pStandardChildItem->setCheckable( true );//设置Item不具有三态pStandardChildItem->setTristate( false );//为Item设置自定义rolepStandardChildItem->setData( MARK_ITEM, ROLE_MARK_TYPE ); //标记该Item为具体的项pStandardItem->appendRow( pStandardChildItem );pStandardItem->setChild( pStandardChildItem->row(),1, new QStandardItem( QString("this is %1").arg( it.key()) ));++i;}在鼠标左键点击TreeView中的Item时,通过对话框显示当前点击的Item的类型:是文件夹还是具体的项?
bool MyDelegate::editorEvent(QEvent * event, QAbstractItemModel * model, const QStyleOptionViewItem & option, const QModelIndex & index){QStandardItemModel* pModel = static_cast<QStandardItemModel*>( model );if (event->type() == QEvent::MouseButtonPress){if (static_cast<QMouseEvent*>(event)->button() == Qt::LeftButton){if (model->data(index, ROLE_MARK_TYPE) == MARK_FOLDER){QMessageBox::information(NULL, "TypeInfo", "this is folder!", QMessageBox::Ok);}else if (model->data(index, ROLE_MARK_TYPE) == MARK_ITEM ){QMessageBox::information(NULL, "TypeInfo", "this is item!", QMessageBox::Ok);}}}return QStyledItemDelegate::editorEvent( event, model, option, index );}
<二>、系统角色的使用
Qt定义好的角色如下:
例子:
bool MyDelegate::editorEvent(QEvent * event, QAbstractItemModel * model, const QStyleOptionViewItem & option, const QModelIndex & index){QStandardItemModel* pModel = static_cast<QStandardItemModel*>( model );if (event->type() == QEvent::MouseButtonPress){if (static_cast<QMouseEvent*>(event)->button() == Qt::LeftButton){if (model->data(index, ROLE_MARK_TYPE) == MARK_FOLDER){QMessageBox::information(NULL, "TypeInfo", "this is folder!", QMessageBox::Ok);}else if (model->data(index, ROLE_MARK_TYPE) == MARK_ITEM ){QMessageBox::information(NULL, "TypeInfo", "this is item!", QMessageBox::Ok);}//设置Item的图标覆盖为某一颜色pModel->itemFromIndex(index)->setData( QColor(0, 255, 0, 200), Qt::DecorationRole);//设置气泡提示信息pModel->itemFromIndex(index)->setData(QString("Tip:%1").arg(pModel->itemFromIndex(index)->text() ), Qt::ToolTipRole);//设置背景色pModel->itemFromIndex(index)->setData(QColor(232, 209, 57, 200), Qt::BackgroundRole);}}return QStyledItemDelegate::editorEvent( event, model, option, index );}效果:
参看:http://www.tuicool.com/articles/FvaYNn
参看:http://www.it165.net/pro/html/201405/14029.html
- QTreeView的使用总结1
- QListView,QTreeView和 QStandardItemModel的简单使用
- QListView,QTreeView和 QStandardItemModel的简单使用
- QTreeView/QAbstractItemModel用法总结
- Qt树形控件QTreeView使用1——节点的添加删除操作
- Qt树形控件QTreeView使用1——节点的添加删除操作
- Qt树形控件QTreeView使用1——节点的添加删除操作
- QTreeView 使用 QStandardItemModel
- QTreeView使用模
- QT中QTreeView使用
- QTreeView使用案例
- QT中QTreeView与QAbstractItemModel使用中QTreeViwe的美化
- QTreeView和QTreeWidget样式表的使用案例
- QTreeView和QTreeWidget样式表的使用案例
- 控件QtreeView的实现
- Qt树形控件QTreeView使用1——节点的添加删除操作 复选框的设置
- Qt树形控件QTreeView使用1——节点的添加删除操作 复选框的设置
- Qt树形控件QTreeView使用1——节点的添加删除操作 复选框的设置
- linux epoll模型
- Unity着色器入门之一步一步来看坐标系变换
- UVALive 4329--Ping pong+树状数组
- Centos下源码包安装lamp常见的几个小问题
- MT7621A 硬件调试总结---(3)
- QTreeView的使用总结1
- AndroidUI设计之 布局管理器 - 详细解析布局实现
- hdu 1195 双向bfs
- 黑马程序员——Java基础——Collection集合的总结
- vs2012编译caffe
- linux常用命令手册
- lucene的基础知识
- 响应式布局的一些要点
- [JQ权威指南]第五天:导航条在项目中运用