一 树形结构体定义 treeitemh
Cpp代码
/
@brief 通用树形结构类
/
class TreeItem
{
public:
TreeItem(const QList<QVariant> &data,TreeItem parent=0 );
~TreeItem();
void appendChild(TreeItem child);
TreeItem child(int row);
int childCount() const;
int columnCount() const;
QVariant data(int column) const;
int row() const;
TreeItem parent();
private:
TreeItem parentItem; // 父结点
QList<TreeItem> childItems; // 子结点列表
QList<QVariant> itemData; // 子节点对应数据
};
二 树形model实现
Cpp代码
#include <QAbstractItemModel>
#include "TreeItemh"
class TagTreeModel : public QAbstractItemModel
{
Q_OBJECT
public:
TagTreeModel(QObject parent = 0);
~TagTreeModel();
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;
// 构建模型数据
void setupModelData(TreeItem parent);
// 更新模型数据
void updateData();
private:
TreeItem rootItem; // 最顶层顶根节点(一个无效的QModelIndex)
};
TagTreeModelcpp
Cpp代码
#include "TagTreeModelh"
#include <QtGui>
TagTreeModel::TagTreeModel(QObject parent):QAbstractItemModel(parent)
{
rootItem=NULL;
updateData();
}
TagTreeModel::~TagTreeModel()
{
delete rootItem;
}
void TagTreeModel::updateData()
{
// 废弃旧的模型数据
if(rootItem)
{
delete rootItem;
rootItem=NULL;
}
QList<QVariant> rootData;
rootData<<"Tag"<<"Type";
rootItem=new TreeItem(rootData);
setupModelData(rootItem);
// 刷新模型
reset();
}
QVariant TagTreeModel::data(const QModelIndex &index, int role) const
{
if (!indexisValid())
return QVariant();
// 添加图标
if(role==Qt::DecorationRole&&indexcolumn()==0)
return QIcon("images/foldpng");
// 显示节点数据值
if(role==Qt::DisplayRole)
{
TreeItem item=static_cast<TreeItem>(indexinternalPointer());
return item->data(indexcolumn());
}
return QVariant();
}
Qt::ItemFlags TagTreeModel::flags(const QModelIndex &index) const
{
if(!indexisValid())
return 0;
return Qt::ItemIsEnabled|Qt::ItemIsSelectable;
}
QVariant TagTreeModel::headerData(int section, Qt::Orientation orientation,int role) const
{
if(orientation==Qt::Horizontal&&role==Qt::DisplayRole)
return rootItem->data(section);
return QVariant();
}
QModelIndex TagTreeModel::index(int row, int column,const QModelIndex &parent) const
{
if(!hasIndex(row,column,parent))
return QModelIndex();
TreeItem parentItem;
if(!parentisValid())
{
parentItem=rootItem;
}else
{
parentItem=static_cast<TreeItem>(parentinternalPointer());
}
TreeItem childItem=parentItem->child(row);
if(childItem)
return createIndex(row,column,childItem); // 展开树形,为子节点建立索引
else
return QModelIndex();
}
QModelIndex TagTreeModel::parent(const QModelIndex &index) const
{
if(!indexisValid())
return QModelIndex();
TreeItem childItem=static_cast<TreeItem>(indexinternalPointer());
TreeItem parentItem=childItem->parent();
// 顶层节点,直接返回空索引
if(parentItem==rootItem)
return QModelIndex();
// 为父结点建立索引
return createIndex(parentItem->row(),0,parentItem);
}
int TagTreeModel::rowCount(const QModelIndex &parent) const
{
TreeItem parentItem;
if(!parentisValid())
parentItem=rootItem;
else
parentItem=static_cast<TreeItem>(parentinternalPointer());
return parentItem->childCount(); // 返回父结点下子结点数目
}
int TagTreeModel::columnCount(const QModelIndex &parent ) const
{
return rootItem->columnCount();
}
// 设置模型数据,构建包含10个根结点,每个根结点包含两个子节点的树形结构
void TagTreeModel::setupModelData(TreeItem parent)
{
for(int i=0;i<10;i++)
{
QList<QVariant> datas;
datas<<QString("设备-%1")arg(i+1)<<QString("类型-%1")arg(i+1);
// 主结点下挂两个子节点
TreeItem primary=new TreeItem(datas,parent);
parent->appendChild(primary);
for(int j=0;j<2;j++)
{
QList<QVariant> ds;
ds<<QString("子设备-%1")arg(j+1)<<QString("子类型-%1")arg(j+1);
primary->appendChild(new TreeItem(ds,primary));
}
}
}
void QAbstractItemView::setModel(QAbstractItemModel model)
{
Q_D(QAbstractItemView);
if (model == d->model)
return;
if (d->model && d->model != QAbstractItemModelPrivate::staticEmptyModel()) {
disconnect(d->model, SIGNAL(destroyed()),
this, SLOT(_q_modelDestroyed()));
disconnect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
this, SLOT(dataChanged(QModelIndex,QModelIndex)));
disconnect(d->model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)),
this, SLOT(_q_headerDataChanged()));
disconnect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
this, SLOT(rowsInserted(QModelIndex,int,int)));
disconnect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
this, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int)));
disconnect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
disconnect(d->model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
this, SLOT(_q_columnsAboutToBeRemoved(QModelIndex,int,int)));
disconnect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
this, SLOT(_q_columnsRemoved(QModelIndex,int,int)));
disconnect(d->model, SIGNAL(columnsInserted(QModelIndex,int,int)),
this, SLOT(_q_columnsInserted(QModelIndex,int,int)));
disconnect(d->model, SIGNAL(modelReset()), this, SLOT(reset()));
disconnect(d->model, SIGNAL(layoutChanged()), this, SLOT(_q_layoutChanged()));
}
d->model = (model model : QAbstractItemModelPrivate::staticEmptyModel());
// These asserts do basic sanity checking of the model
Q_ASSERT_X(d->model->index(0,0) == d->model->index(0,0),
"QAbstractItemView::setModel",
"A model should return the exact same index "
"(including its internal id/pointer) when asked for it twice in a row");
Q_ASSERT_X(d->model->index(0,0)parent() == QModelIndex(),
"QAbstractItemView::setModel",
"The parent of a top level index should be invalid");
if (d->model != QAbstractItemModelPrivate::staticEmptyModel()) {
connect(d->model, SIGNAL(destroyed()),
this, SLOT(_q_modelDestroyed()));
connect(d->model, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
this, SLOT(dataChanged(QModelIndex,QModelIndex)));
connect(d->model, SIGNAL(headerDataChanged(Qt::Orientation,int,int)),
this, SLOT(_q_headerDataChanged()));
connect(d->model, SIGNAL(rowsInserted(QModelIndex,int,int)),
this, SLOT(rowsInserted(QModelIndex,int,int)));
connect(d->model, SIGNAL(rowsAboutToBeRemoved(QModelIndex,int,int)),
this, SLOT(rowsAboutToBeRemoved(QModelIndex,int,int)));
connect(d->model, SIGNAL(rowsRemoved(QModelIndex,int,int)),
this, SLOT(_q_rowsRemoved(QModelIndex,int,int)));
connect(d->model, SIGNAL(columnsAboutToBeRemoved(QModelIndex,int,int)),
this, SLOT(_q_columnsAboutToBeRemoved(QModelIndex,int,int)));
connect(d->model, SIGNAL(columnsRemoved(QModelIndex,int,int)),
this, SLOT(_q_columnsRemoved(QModelIndex,int,int)));
connect(d->model, SIGNAL(columnsInserted(QModelIndex,int,int)),
this, SLOT(_q_columnsInserted(QModelIndex,int,int)));
connect(d->model, SIGNAL(modelReset()), this, SLOT(reset()));
connect(d->model, SIGNAL(layoutChanged()), this, SLOT(_q_layoutChanged()));
}
<span style="color: #FF0000;">
QItemSelectionModel selection_model = new QItemSelectionModel(d->model, this);
</span>
//这个TMD 怎么控制啊,大爷的,每次set 都来一个,我还没看到那边进行处理的。
//但可以肯定的是不断的setModel 我感觉100% 内存泄露
connect(d->model, SIGNAL(destroyed()), selection_model, SLOT(deleteLater()));
setSelectionModel(selection_model);
reset(); // kill editors, set new root and do layout
}
这个需要重写一些model的方法
当然你需要编辑也要实现自己的delegate
class MyTableDelgate : public QStyledItemDelegate
{
Q_OBJECT
public:
explicit MyTableDelgate(QObject parent = 0);
protected:
//basic function for a read-only delegate, you can draw anything with the painter
void paint(QPainter painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
//edit 5 function
QWidget createEditor(QWidget parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
void setEditorData(QWidget editor, const QModelIndex &index) const;
void setModelData(QWidget editor, QAbstractItemModel model, const QModelIndex &index) const;
void updateEditorGeometry ( QWidget editor, const QStyleOptionViewItem & option, const QModelIndex & index ) const;
private:
QLineEdit m_LineEdit;
};
model
class MyTableDelgate : public QStyledItemDelegate
{
Q_OBJECT
public:
explicit MyTableDelgate(QObject parent = 0);
protected:
//basic function for a read-only delegate, you can draw anything with the painter
void paint(QPainter painter, const QStyleOptionViewItem &option, const QModelIndex &index) const;
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const;
//edit 5 function
QWidget createEditor(QWidget parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
void setEditorData(QWidget editor, const QModelIndex &index) const;
void setModelData(QWidget editor, QAbstractItemModel model, const QModelIndex &index) const;
void updateEditorGeometry ( QWidget editor, const QStyleOptionViewItem & option, const QModelIndex & index ) const;
};
以上就是关于如何给QTreeView的节点显示图标全部的内容,包括:如何给QTreeView的节点显示图标、求助QlistView-CSDN论坛、怎么用QTableView修改数据库内容等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)