Qt之Model-View架构

简述

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

效果图

代码

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

    为了判断一个对象是否包含自定义属性而不是原型链上的属性,我们需要使用继承自 Object.prototype 的 hasOwnProperty方法.hasOwnProperty 是 JavaScrip ...

  2. 同一性(identical)

    f(x)=x,表明 f(⋅) 为同一函数. A 与 B 具有 360° 的区别 A 向左转,再向右转 ⇒ A A 向左转,向左转,向后转 ⇒ A

  3. 我是如何进行code review的

    众所周知,代码审查是软件开发过程中十分重要的环节,楼主结合自己的实际工作经验,和大家分享一下在实际工作中代码审查是如何开展的, 笔者水平有限,若有错误和纰漏,还请大家指正. 代码审查的阻力 我想不通公 ...

  4. sql知识收藏小总结

    div { background-color: #eee; border-radius: 3px; border: 1px solid #999; padding: 4px; display: blo ...

  5. elasticsearch start

    启动.停止服务 默认官方版启动: linux:./bin/elasticsearch start window:直接运行bin/elasticsearch.bat 默认官方版停止: linux:kil ...

  6. Cordova 返回键切换后台

    这里需要用到 cordova-plugin-backbutton 这个插件 1.安装插件,命令窗口输入(当前目录是你项目所在的目录) cordova plugin add cordova-plugin ...

  7. webpack打包不引入vue、echarts等公共库

    如果我们打包的时候不想将vue.echarts等公共库包含在内,需要配置两处地方, 以下以基于vue-cli生成的项目为基准: 1webpack配置: // webpack.base.conf.js ...

  8. background意识(两)

    今天看到了有关学习的价值的文章background于 [0积分下载我的小Demo]

  9. HDU-4432-Sum of divisors ( 2012 Asia Tianjin Regional Contest )

    Sum of divisors Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  10. Android笔记--自定义控件仿遥控器的圆形上下左右OK圆盘按钮

    原文:Android笔记--自定义控件仿遥控器的圆形上下左右OK圆盘按钮 上面就是几张预览图!代码在最底下 主要就两个步骤,画图.监听点击 1.整个控件基本上是一步步画出来的,重写onDraw方法开始 ...