Qt 自定义treemodel

         要实现一个treemodel,必须得从QAbstractItemModel派生,并且还必须有拥有一个树结构的数据。对于树形的treemodel,他的每一个我们所看到的第一层index都有一个共同的根节点,大概如下

 根节点

0行    |- - - - - -- -

1行    | -------------

 2行   |--------------

 0行           |---- -- - - - - - - --

 1行           |- - - -- - - - -- - - -

  3行  |

class Node {
public:
	enum Type {ROOT,TYPE,RESULT,PARAMETER,ISCHECK};

	Node();
	Node(Type t,const QString &str);
	~Node();

	Type type;
	QString name;
	Node *parent;
	QList<Node*> children;
};
    Node类,构成了一个树形的数据结构,我们假设这个树结构的数据拥有一个共同的根节点rootnode,它对应了treemodel的根节点。那么这个rootNode的应该如下

rootNode->parent = 0;

 其children就是我们需要显示的每一个节点的值。
QVariant ResultTreeModel::data(const QModelIndex& index,int role) const {
	Node* node = nodeFromIndex(index);

	if(!node)
		return QVariant();

	if(index.column() == 0) {
		if (node->parent == rootNode) {
			if (role == Qt::ForegroundRole) {
				if (index.row() == currentCheck) {
					return QVariant(QBrush(qRgb(185,185,185)));
				}
			} else if (role == Qt::DisplayRole) {
				return node->name;
			} else {
				return QVariant();
			}
		}
		if (node->name == "OK") {
			if (role == Qt::ForegroundRole) {
				return QVariant(QBrush(Qt::green));
			} else if (role == Qt::DisplayRole) {
				return node->name;
			} else {
				return QVariant();
			}
		} else if (node->name == "BAD") {
			if (role == Qt::ForegroundRole) {
				return QVariant(QBrush(Qt::red));
			} else if (role == Qt::DisplayRole) {
				return node->name;
			} else {
				return QVariant();
			}
		} else {
			if (role != Qt::DisplayRole) {
				return QVariant();
			} else {
				return node->name;
			}
		}
	}
	return QVariant();
}

/*
 * 返回当前index的对应的node
 */
Node* ResultTreeModel::nodeFromIndex(const QModelIndex& index) const {
	if(index.isValid())
		return static_cast<Node*>(index.internalPointer());
	else
		return rootNode;
}

因为是直接重载的QAbstractItemModel,所以还必须实现parent和index函数。
//Returns the index of the item in the model specified by the given row, column and parent index.
//返回指定index的(row,column)位置的子节点。
 QModelIndex ResultTreeModel::index(int row, int column, const QModelIndex& parent) const {
	if(!rootNode || row < 0 || column < 0) {
		return QModelIndex();
	}
	Node* parentNode = nodeFromIndex(parent);
	Node* childNode = parentNode->children.value(row);

	if(!childNode)
		return QModelIndex();
	return createIndex(row,column,childNode);
}
//Returns the parent of the model item with the given index. If the item has no parent, an invalid QModelIndex is returned.
// 返回指定index的父节点,如果不存在父节点,则返回无效的index。
QModelIndex ResultTreeModel::parent(const QModelIndex& child) const {
	Node* node = nodeFromIndex(child);
        //如果当前节点的node为空,则返回无效index 
        if(!node)
		return QModelIndex();
        //获取当前节点的父节点值,如果为空,返回无效index
        Node* parentNode = node->parent;
	if(!parentNode)
		return QModelIndex();
        //当前节点的父节点的父节点,如果为空,返回无效index
        Node* gradparentNode = parentNode->parent;
	if(!gradparentNode)
		return QModelIndex();
        //找到当前节点的父节点在它的父节点下的行号
	int row = gradparentNode->children.indexOf(parentNode);
        //生成对应行号的index。
	return createIndex(row,0,parentNode);
}

   然后就是还得实现columnCount和rowCount函数。

int ResultTreeModel::rowCount(const QModelIndex& parent) const {
	if(parent.column() > 0)
		return 0;
	Node* parentNode = nodeFromIndex(parent);
	if(!parentNode)
		return 0;
	return parentNode->children.count();
}

int ResultTreeModel::columnCount(const QModelIndex& parent) const {
	return 1;
}




你可能感兴趣的:(数据结构,Class,qt)