* [简述](http://blog.csdn.net/ly305750665/article/details/79016794#%E7%AE%80%E8%BF%B0)
* [效果图](http://blog.csdn.net/ly305750665/article/details/79016794#%E6%95%88%E6%9E%9C%E5%9B%BE)
* [代码](http://blog.csdn.net/ly305750665/article/details/79016794#%E4%BB%A3%E7%A0%81)
* [结尾](http://blog.csdn.net/ly305750665/article/details/79016794#%E7%BB%93%E5%B0%BE)
为什么会用这个模式,这里我就不解释了,可以看下 豆子哥的见解 。这里我只是如何去使用的。供大家共同探讨学习,主要是参考了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
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
{
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
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,因权限问题暂时不能上传工程文件。
手机扫一扫
移动阅读更方便
你可能感兴趣的文章