继续向RSS阅读器迈进。
创建一个TreeModel,参考并修改自SimpleTreeModel例子
------------
这个例子我没有完全搞明白数是怎么创建的,
我猜想相当于接口约束的方式,规范了QAbstractItemModel必须要实现Index(row,column,parent)方法。
QTreeModel获取(0,0,QModelIndex())位置的QModelIndex也就是根结点。
其中QModelIndex是个无效的Index。然后通过data(index,role)获得index指定位置的指定角色的数据。比如说我关注的图标数据
flags方法和headerData方法我不关心
===========
然后剩下就是广度有限或者深度优先创建树的展现。
通过rowCount(parent)获取当前Index的子节点数
通过ColumnCount(parent)获取当前Index的字节点的列数。
通过Index(row,Column,parent)获得指定的节点index
通过data(index,role)获得指定节点的数据
===========
我的树建立在Sqlite基础上,目前尚未解决编码问题,有高手指点一定事半功倍,不胜感激。
我的数据是通过SqlBrowser插入的,通过Qt读出后,应该是编码的问题,看不到标题。我想问QString有没有办法转成GB2312。我对编码不熟,如果能给讲讲Qt中的字符编码就更好了。 貌似Qt对查询得到的结果进行了正确的编码,看不到标题完全是代码写错了 =================
下面贴代码:
TreeItem.h和TreeItem.cpp原封不动
TreeModel.h和TreeModel.cpp涉及到
创建树的方法被替换成通过Strategy模式创建,代码如下:
TreeModel.h#ifndef TREEMODEL_H
#define TREEMODEL_H
#include <QAbstractItemModel>
#include <QModelIndex>
#include <QVariant>
#include <QSqlQuery>
#include <QMessageBox>
class TreeItem;
class TreeStrategy{public: virtual ~TreeStrategy(){}; virtual void buildTree(TreeItem *root){QMessageBox::information(0,"create","create");};}; class TreeModel : public QAbstractItemModel
{
Q_OBJECT
public:
TreeModel(TreeStrategy *treeStrategy, QObject *parent = 0); ~TreeModel();
QVariant data(const QModelIndex &index, int role) const;
Qt::ItemFlags flags(const QModelIndex &index) const;
QVariant headerData(int section, Qt::Orientation orientation,
int role = Qt::DisplayRole) const;
QModelIndex index(int row, int column,
const QModelIndex &parent = QModelIndex()) const;
QModelIndex parent(const QModelIndex &index) const;
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
private:
TreeItem *rootItem;
};
#endif
TreeModel.cpp#include <QtGui>
#include <QMessageBox>
#include "treeitem.h"
#include "treemodel.h"
TreeModel::TreeModel(TreeStrategy *treeStrategy, QObject *parent) : QAbstractItemModel(parent){ QList<QVariant> rootData; rootData << tr("频道列表"); rootItem = new TreeItem(rootData); treeStrategy->buildTree(rootItem); //对于C++中关于指针,引用,对象的多态忘光了 //在Delphi中所有的对象都是引用,省掉了很多麻烦} TreeModel::~TreeModel()
{
delete rootItem;
}
int TreeModel::columnCount(const QModelIndex &parent) const
{
if (parent.isValid())
return static_cast<TreeItem*>(parent.internalPointer())->columnCount();
else
return rootItem->columnCount();
}
QVariant TreeModel::data(const QModelIndex &index, int role) const
{
/* if (!index.isValid()) return QVariant(); if (role != Qt::DisplayRole) return QVariant(); TreeItem *item = static_cast<TreeItem*>(index.internalPointer()); return item->data(index.column());*/ if (!index.isValid()) return QVariant(); TreeItem *item = static_cast<TreeItem*>(index.internalPointer()); switch(role) { case Qt::DisplayRole: { return item->data(index.column()); break; } case Qt::DecorationRole: { QPixmap pixmap; pixmap.loadFromData(item->data(1).toByteArray()); return pixmap; } default: return QVariant(); }}
Qt::ItemFlags TreeModel::flags(const QModelIndex &index) const
{
if (!index.isValid())
return 0;
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
}
QVariant TreeModel::headerData(int section, Qt::Orientation orientation,
int role) const
{
if (orientation == Qt::Horizontal && role == Qt::DisplayRole)
return rootItem->data(section);
return QVariant();
}
QModelIndex TreeModel::index(int row, int column, const QModelIndex &parent)
const
{
if (!hasIndex(row, column, parent))
return QModelIndex();
TreeItem *parentItem;
if (!parent.isValid())
parentItem = rootItem;
else
parentItem = static_cast<TreeItem*>(parent.internalPointer());
TreeItem *childItem = parentItem->child(row);
if (childItem)
return createIndex(row, column, childItem);
else
return QModelIndex();
}
QModelIndex TreeModel::parent(const QModelIndex &index) const
{
if (!index.isValid())
return QModelIndex();
TreeItem *childItem = static_cast<TreeItem*>(index.internalPointer());
TreeItem *parentItem = childItem->parent();
if (parentItem == rootItem)
return QModelIndex();
return createIndex(parentItem->row(), 0, parentItem);
}
int TreeModel::rowCount(const QModelIndex &parent) const
{
TreeItem *parentItem;
if (parent.column() > 0)
return 0;
if (!parent.isValid())
parentItem = rootItem;
else
parentItem = static_cast<TreeItem*>(parent.internalPointer());
return parentItem->childCount();
}
其中紫色部分是修改过得代码。[ 此贴被wvins在2008-11-09 20:19重新编辑 ]