您的位置:首页 > 编程语言 > Qt开发

Qt之Model-View架构(雨田哥的博客)

2016-12-14 23:57 337 查看

Qt之Model-View架构

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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: