Qt之Model-View架构

简述

为什么会用这个模式,这里我就不解释了,可以看下 豆子哥的见解 。这里我只是如何去使用的。供大家共同探讨学习,主要是参考了Qt的Demo。

效果图

代码

//主代码界面QMvcTest.cpp
void QMvcTest::initControl()
{
QCustomItemModel* customModel = new QCustomItemModel(QJsonArray(), ui.treeView);
ItemDelegate *delegate = new ItemDelegate(ui.treeView);
ui.treeView->setModel(customModel);
delegate->setView(ui.treeView);
ui.treeView->setAnimated(true);
ui.treeView->setMouseTracking(true);
ui.treeView->setItemDelegate(delegate);
ui.treeView->setCursor(Qt::PointingHandCursor); const QModelIndex&& curIndex = customModel->index(0, 0).child(0, 0);
ui.treeView->setCurrentIndex(curIndex);
connect(delegate, SIGNAL(expanded(const QModelIndex &)), this, SLOT(onTreeViewExpanded(const QModelIndex &)));
} void QMvcTest::onTreeViewExpanded(const QModelIndex &index)
{
bool bExpanded = ui.treeView->isExpanded(index);
if (!bExpanded)
{
ui.treeView->expand(index);
}
else
{
ui.treeView->collapse(index);
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
//QCustomItemModel.cpp
QCustomItemModel::QCustomItemModel(const QJsonArray &data, QObject *parent)
: QAbstractItemModel(parent)
{
QJsonArray objChildArray = { QStringLiteral("雨田哥1号"), QStringLiteral("雨田哥2号"), QStringLiteral("雨田哥3号"), QStringLiteral("雨田哥4号"), QStringLiteral("雨田哥5号") };
QJsonObject obj{ { QStringLiteral("雨田哥"), objChildArray }
};
QJsonArray array = { obj, obj, obj }; QVector<QVariant> rootData;
rootData << "";
rootItem = new TreeItem(rootData);
setModelData(array);
} QCustomItemModel::~QCustomItemModel()
{
delete rootItem;
} int QCustomItemModel::columnCount(const QModelIndex & /* parent */) const
{
return rootItem->columnCount();
} int QCustomItemModel::rowCount(const QModelIndex &parent) const
{
TreeItem *parentItem = getItem(parent);
return parentItem->childCount();
} QVariant QCustomItemModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant(); TreeItem *item = getItem(index);
if (item == nullptr)
{
return QVariant();
} if (role == Qt::DisplayRole || role == Qt::EditRole)
{
return item->data(index.column());
}
else if (role == Qt::UserRole + 1)
{
//是否是子节点
if (item->childCount() == 0)
{
return true;
}
return false;
}
else
{
return QVariant();
}
} Qt::ItemFlags QCustomItemModel::flags(const QModelIndex &index) const
{
if (!index.isValid())
return 0;
TreeItem *item = getItem(index);
if (item && item->childCount() > 0)
{
return Qt::NoItemFlags;
}
return Qt::ItemIsEditable | QAbstractItemModel::flags(index);
} TreeItem *QCustomItemModel::getItem(const QModelIndex &index) const
{
if (index.isValid()) {
TreeItem *item = static_cast<TreeItem*>(index.internalPointer());
if (item)
return item;
}
return rootItem;
} QVariant QCustomItemModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
return rootItem->data(section); return QVariant();
} QModelIndex QCustomItemModel::index(int row, int column, const QModelIndex &parent) const
{
if (parent.isValid() && parent.column() != 0)
return QModelIndex();
TreeItem *parentItem = getItem(parent); TreeItem *childItem = parentItem->child(row);
if (childItem)
return createIndex(row, column, childItem);
else
return QModelIndex();
} bool QCustomItemModel::insertColumns(int position, int columns, const QModelIndex &parent)
{
bool success; beginInsertColumns(parent, position, position + columns - 1);
success = rootItem->insertColumns(position, columns);
endInsertColumns(); return success;
} bool QCustomItemModel::insertRows(int position, int rows, const QModelIndex &parent)
{
TreeItem *parentItem = getItem(parent);
bool success; beginInsertRows(parent, position, position + rows - 1);
success = parentItem->insertChildren(position, rows, rootItem->columnCount());
endInsertRows(); return success;
} QModelIndex QCustomItemModel::parent(const QModelIndex &index) const
{
if (!index.isValid())
return QModelIndex(); TreeItem *childItem = getItem(index);
TreeItem *parentItem = childItem->parent(); if (parentItem == rootItem)
return QModelIndex(); return createIndex(parentItem->childNumber(), 0, parentItem);
} bool QCustomItemModel::removeColumns(int position, int columns, const QModelIndex &parent)
{
bool success; beginRemoveColumns(parent, position, position + columns - 1);
success = rootItem->removeColumns(position, columns);
endRemoveColumns(); if (rootItem->columnCount() == 0)
removeRows(0, rowCount()); return success;
} bool QCustomItemModel::removeRows(int position, int rows, const QModelIndex &parent)
{
TreeItem *parentItem = getItem(parent);
bool success = true; beginRemoveRows(parent, position, position + rows - 1);
success = parentItem->removeChildren(position, rows);
endRemoveRows(); return success;
} bool QCustomItemModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (role == Qt::EditRole)
{
TreeItem *item = getItem(index);
bool result = item->setData(index.column(), value); if (result)
emit dataChanged(index, index);
return result;
}
else if (role == Qt::FontRole)
{
TreeItem *item = getItem(index);
if (item && item->childCount() == 0)
{
item->m_itemFontIsBold = value.toBool();
}
return true;
}
else
{
return false;
}
} bool QCustomItemModel::setHeaderData(int section, Qt::Orientation orientation,
const QVariant &value, int role)
{
if (role != Qt::EditRole || orientation != Qt::Horizontal)
return false; bool result = rootItem->setData(section, value); if (result)
emit headerDataChanged(orientation, section, section); return result;
} void QCustomItemModel::setModelData(const QJsonArray &data)
{
for (int nRootIndex = 0; nRootIndex < data.size(); nRootIndex++)
{
const QJsonObject&& obj = data.at(nRootIndex).toObject();
for (auto itor = obj.begin(); itor != obj.end(); itor++)
{
const QString&& key = itor.key();
const QJsonArray&& childAray = itor.value().toArray(); QVector<QVariant> columnData;
columnData << key;
rootItem->insertChildren(nRootIndex, 1, rootItem->columnCount()); TreeItem* parent = rootItem->child(nRootIndex);
parent->setData(0, key); for (int index = 0; index < childAray.size(); index++)
{
parent->insertChildren(index, 1, rootItem->columnCount());
parent->child(index)->setData(0, childAray.at(index).toString());
}
}
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
//TreeItem.cpp
TreeItem::TreeItem(const QVector<QVariant> &data, TreeItem *parent)
{
m_itemFontIsBold = true;
parentItem = parent;
itemData = data;
} TreeItem::~TreeItem()
{
qDeleteAll(childItems);
} TreeItem *TreeItem::child(int number)
{
return childItems.value(number);
} int TreeItem::childCount() const
{
return childItems.count();
} int TreeItem::childNumber() const
{
if (parentItem)
return parentItem->childItems.indexOf(const_cast<TreeItem*>(this)); return 0;
} int TreeItem::columnCount() const
{
return itemData.count();
} QVariant TreeItem::data(int column) const
{
return itemData.value(column);
} bool TreeItem::insertChildren(int position, int count, int columns)
{
if (position < 0 || position > childItems.size())
return false; for (int row = 0; row < count; ++row) {
QVector<QVariant> data(columns);
TreeItem *item = new TreeItem(data, this);
childItems.insert(position, item);
} return true;
} bool TreeItem::insertColumns(int position, int columns)
{
if (position < 0 || position > itemData.size())
return false; for (int column = 0; column < columns; ++column)
itemData.insert(position, QVariant()); foreach (TreeItem *child, childItems)
child->insertColumns(position, columns); return true;
} TreeItem *TreeItem::parent()
{
return parentItem;
} bool TreeItem::removeChildren(int position, int count)
{
if (position < 0 || position + count > childItems.size())
return false; for (int row = 0; row < count; ++row)
delete childItems.takeAt(position); return true;
} bool TreeItem::removeColumns(int position, int columns)
{
if (position < 0 || position + columns > itemData.size())
return false; for (int column = 0; column < columns; ++column)
itemData.remove(position); foreach (TreeItem *child, childItems)
child->removeColumns(position, columns); return true;
} bool TreeItem::setData(int column, const QVariant &value)
{
if (column < 0 || column >= itemData.size())
return false; itemData[column] = value;
return true;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
//ItemDelegate.cpp
void ItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QStyleOptionViewItem viewOption(option);
QStyledItemDelegate::paint(painter, viewOption, index); bool bExpanded = false;
if (m_treeView != NULL)
{
const QAbstractItemModel *model = index.model();
if (!model->hasChildren(index))
{
return;
}
bExpanded = m_treeView->isExpanded(index);
} QPixmap pixmap = bExpanded ? QPixmap(m_expandIconName) : QPixmap(m_collapseIconName);
QRect decorationRect = QRect(viewOption.rect.left() + 14, viewOption.rect.top() + 12, m_pixmapHeight, m_pixmapWidth);
painter->drawPixmap(decorationRect, pixmap);
} bool ItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index)
{
if (event->type() == QEvent::MouseButtonPress && Qt::LeftButton == qApp->mouseButtons())
{
m_treeView->update();
emit expanded(index);
}
return QStyledItemDelegate::editorEvent(event, model, option, index);
} void ItemDelegate::setView(QTreeView *treeView)
{
m_treeView = treeView;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
//QSS样式
QTreeView
{
background-color: #ffffff;
show-decoration-selected: 1;
outline:0px;
} QTreeView::item {
background-color:transparent;
font-family: Microsoft YaHei;
font-size: 12px;
color: #666666;
text-align:left;
height:32px;
padding-left:22px;
} QTreeView::item:has-children {
background-color:transparent;
font-family: Microsoft YaHei;
font-size: 12px;
color: #333333;
text-align:left;
height:32px;
padding-left:22px;
} QTreeView::item:hover,QTreeView::item:selected {
background-color:#D3EFFF;
font-size: 12px;
color: #00A1FF;
border:0px;
text-align:left;
} QTreeView::branch:has-children:!has-siblings:closed,
QTreeView::branch:closed:has-children:has-siblings {
border-image: none;
image: url(:/QMvcTest/Resources/smallPackup.png:);
} QTreeView::branch:open:has-children:!has-siblings,
QTreeView::branch:open:has-children:has-siblings {
border-image: none;
image: url(:/QMvcTest/Resources/smallExp.png);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47

结尾

只为记录,只为分享! 愿所写能对你有所帮助。不忘记点个赞,谢谢~ 
需要原工程文件的可以加我QQ,因权限问题暂时不能上传工程文件。

http://blog.csdn.net/ly305750665/article/details/79016794

Qt之Model-View架构(雨田哥的博客)的更多相关文章

  1. Qt 学习之路 2(41):model/view 架构

    Qt 学习之路 2(41):model/view 架构 豆子 2013年1月23日 Qt 学习之路 2 50条评论 有时,我们的系统需要显示大量数据,比如从数据库中读取数据,以自己的方式显示在自己的应 ...

  2. 第15.23节 PyQt(Python+Qt)入门学习:Model/View架构中QListView视图配套Model的开发使用

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.概述 QListView理论上可以和所有QAbstractItemModel派生的类如QStri ...

  3. 第15.22节 PyQt(Python+Qt)入门学习:Model/View架构详解

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.简介 在PyQt和Qt中,Model/View架构是图形界面开发时用于管理数据和界面展现方式的关 ...

  4. PyQt(Python+Qt)学习随笔:Model/View架构中的Model模型概念

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 Model/View架构中的Model模型Model与数据源通信,为体系结构中的其他组件提供数据接口 ...

  5. PyQt(Python+Qt)学习随笔:Model/View架构概述

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.引言 模型-视图-控制器(Model-View-Controller,简称MVC)是一种源于Sm ...

  6. 第15.18节 PyQt(Python+Qt)入门学习:Model/View架构中视图Item Views父类详解

    老猿Python博文目录 老猿Python博客地址 一.概述 在PyQt图形界面中,支持采用Model/View架构实现数据和界面逻辑分离,其中Model用于处理数据存储,View用于界面数据展现,当 ...

  7. PyQt(Python+Qt)学习随笔:model/view架构中类QStandardItemModel的使用方法

    老猿Python博文目录 老猿Python博客地址 一.概述 QStandardItemModel是QAbstractItemModel的派生类,用于在Model/View架构中存储自定义数据的通用模 ...

  8. 第15.27节 PyQt(Python+Qt)入门学习:Model/View架构中的便利类QTreeWidget详解

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.引言 树部件(Tree Widget)是Qt Designer中 Item Widgets(It ...

  9. 第十四章、Model/View开发:Model/View架构程序设计模式

    老猿Python博文目录 专栏:使用PyQt开发图形界面Python应用 老猿Python博客地址 一.简介 在PyQt和Qt中,Model/View架构是图形界面开发时用于管理数据和界面展现方式的关 ...

随机推荐

  1. 获取全局上下文(getApplicationContext)_创建Shared Preference工具类_实现自动登录

    获取全局上下文(getApplicationContext)_创建Shared Preference工具类_实现自动登录 ===========================获取全局上下文(getA ...

  2. matlab 格式化文本文件的解析

    比如这样一种格式化的文本文件,文件说明及下载地址:/pub/machine-learning-databases/statlog/german/ 的索引 fid = fopen('german.dat ...

  3. css3中的制作动画小总结

    系列教程 CSS3属性中有关于制作动画的三个属性:Transform,Transition,Animation: Transform 在CSS3中transform主要包括以下几种:旋转rotate. ...

  4. 定制Octopress

    在 github pages 上搭建好 octopress 博客之后,博客的基本功能就能使用了.如果想自己定制也是没问题的,octopress 有较详尽的官方文档,原则上有问题求助官方即可:octop ...

  5. Android如何获得系统版本

    如何获得Android系统版本 项目移植中,遇到需要区分不同系统版本的问题.于是查找相关方法如下: android.os.Build类提供了当前系统信息. 可用if (Build.VERSION.SD ...

  6. Project Euler:Problem 28 Number spiral diagonals

    Starting with the number 1 and moving to the right in a clockwise direction a 5 by 5 spiral is forme ...

  7. 陈硕 - Linux 多线程服务端编程 - muduo 网络库作者

    http://chenshuo.com/book/ Muduo网络库源码分析(一) EventLoop事件循环(Poller和Channel)http://blog.csdn.net/nk_test/ ...

  8. SQL中关键字的执行顺序

    作为一个SQL新手,看到每种不熟悉的关键字时已经够迷茫了,可往往见到的语句关键字顺序还是各种各样,太难理解了.网上搜索了两篇文章,总结一下: 关于Sql关键字SELECT FROM GROUP ORD ...

  9. oracle备份和升级数据库

    同oracle用户登录数据库驻留server.例如,主文件夹/home./oracle.运行以下命令来执行备份操作. sqlplus /nolog connect /as sysdba sql> ...

  10. Effective JavaScript Item 38 调用父类的构造函数在子类的构造函数

    作为这一系列Effective JavaScript的读书笔记. 在一个游戏或者图形模拟的应用中.都会有场景(Scene)这一概念.在一个场景中会包括一个对象集合,这些对象被称为角色(Actor). ...