Model

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
#include "ModelTree.h"
#include "Common.h"
#include "DaRecord.h"
#include "ScopeTailed.h"

/*最重要的就是对interpointer()这个内部指针的运用
与QTableView不同的是多了parent()和index()函数的重写,这也是关键之处
*/

ModelTree::ModelTree()
{
header_ <<....;
}

ModelTree::~ModelTree()
{
}

bool ModelTree::loadRoots()
{
beginResetModel();
mode_ = FULL;
root_.children_.clear();
root_.spbm_ = "0";
ScopeTailed endReset([this](){endResetModel(); });
DaRecord da;
if (!da.expandItem(root_))
return false;
return true;
}

void ModelTree::loadResult(RecordTree &root)
{
beginResetModel();
mode_ = RESULT;
root_ = root;
root_.buildTree();
endResetModel();
}

QVariant ModelTree::headerData(int section, Qt::Orientation orientation, int role /* = Qt::DisplayRole */) const
{
if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
return header_[section];
return QVariant();
}

int ModelTree::columnCount(const QModelIndex &parent /* = QModelIndex() */) const
{
return header_.count();
}

QVariant ModelTree::data(const QModelIndex &index, int role /* = Qt::DisplayRole */) const
{
if (role==Qt::DisplayRole && index.isValid())
{
RecordTree *pRec = static_cast<RecordTree*>(index.internalPointer());
switch (index.column())
{
case 0:return pRec->spmc_;
case 1:return pRec->spbm_;
case 2:return pRec->zs_;
case 3:return pRec->slv_.toString();
}
}
return QVariant();
}

int ModelTree::rowCount(const QModelIndex &parent /* = QModelIndex() */) const
{
if (!parent.isValid())
return root_.children_.count();
RecordTree *pRec = static_cast<RecordTree*>(parent.internalPointer());
if (mode_==FULL && !pRec->expanded_)
{
DaRecord da;
da.expandItem(*pRec);
}

return pRec->children_.count();
}

QModelIndex ModelTree::index(int row, int column, const QModelIndex &parent /* = QModelIndex() */) const
{
if (!parent.isValid())
{
if (row < root_.children_.count())
return createIndex(row, column, const_cast<RecordTree*>(&root_.children_[row]));
else
return QModelIndex();
}
RecordTree *pRec = static_cast<RecordTree*>(parent.internalPointer());
return createIndex(row, column, &pRec->children_[row]);
}

QModelIndex ModelTree::parent(const QModelIndex &index) const
{
RecordTree *rec = static_cast<RecordTree*>(index.internalPointer());
if (rec->parent_ == &root_)
return QModelIndex();
return createIndex(rec->parent_->rowIndex_, 0, rec->parent_);
}

结构

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
#pragma once
#include <QString>
#include <QList>
#include "Common.h"
#include "DatabaseAccess.h"

class RecordTree
{
public:
RecordTree();
~RecordTree();

public:
QString spbm_;
QString spmc_;
QString pid_;
QString zs_;
Currency slv_;
bool nodeType_; //1为父节点 0没有子节点

QList<RecordTree> children_;
bool expanded_ = false;
int rowIndex_ = 0;
RecordTree *parent_ = nullptr;

//创建一个树结构的数据
void buildTree()
{
for (int i = 0; i < children_.count(); i++)
{
RecordTree &child = children_[i];
child.parent_ = this;
child.rowIndex_ = i;
child.buildTree();
}
}

//根据所传来的字段找到这个树结构的数据
RecordTree *search(QString spbm)
{
if (spbm_ == spbm)
return this;
for (RecordTree &child : children_)
{
RecordTree *result = child.search(spbm);
if (result)
return result;
}
return nullptr;
}
};

加载数据

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
#include "DaRecord.h"
#include "Global.h"
#include "Database.h"

DaRecord::DaRecord()
{
setDatabase(global<Database>()->db());
}

DaRecord::~DaRecord()
{
}

bool DaRecord::selectByPid(QString &pid, QList<RecordTree> &commodity)
{
QString condition = QString("pid='%1'").arg(pid);
if (!selectBy(condition, commodity))
return false;
return true;
}

bool DaRecord::expandItemImpl(RecordTree &root)
{
QList<RecordTree> treeList;
if (!selectByPid(root.spbm_, treeList))
return false;
for (RecordTree &res : treeList)
{
res.parent_ = &root;
res.rowIndex_ = root.children_.count();
root.children_ << res;
}
root.expanded_ = true;
return true;
}

bool DaRecord::expandItem(RecordTree &root)
{
if (!expandItemImpl(root))
return false;
for (RecordTree &res : root.children_)
if (!expandItemImpl(res))
return false;

return true;
}


bool DaRecord::selectBySpbm(QString &spbm, RecordTree &res)
{
QString selectSql = QString("spbm='%1'").arg(spbm);
QList<RecordTree> resList;
if (!selectBy(selectSql, resList))
return false;
res = resList.first();

return true;
}

bool DaRecord::selectBykeyword(QString &keyword, QList<RecordTree> &commomdity)
{
QString condition = QString("spmc like '%%1% or zs like '%%2%'").arg(keyword).arg(keyword);
if (!selectBy(condition, commomdity))
return false;

return true;
}
//...(查找项目)
bool DaRecord::searchItem(QString &keyword, RecordTree &root)
{
QList<RecordTree> commoditys;
if (!selectBykeyword(keyword, commoditys))
return false;
for (auto &cur : commoditys)
{
RecordTree *parent = nullptr;
while (cur.pid_ != "0")
{
parent = root.search(cur.spbm_);
if (!parent)
{
RecordTree newParent;
if (!selectBySpbm(cur.pid_, newParent))
return false;
root.children_ << cur;
cur = newParent;
}
else
{
parent->children_ << cur;
break;
}
}
if (!parent)
root.children_ << cur;
}
return true;
}

转载自:https://www.cnblogs.com/adeng-x/p/8097864.html