谁熟悉QTreeView+QAbstractItemModel 多选删除功能

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了谁熟悉QTreeView+QAbstractItemModel 多选删除功能相关的知识,希望对你有一定的参考价值。

参考技术A 一. 树形结构体定义 treeitem.h
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 "TreeItem.h"

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)
;

TagTreeModel.cpp
Cpp代码
#include "TagTreeModel.h"
#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 (!index.isValid())
return QVariant();

// 添加图标
if(role==Qt::DecorationRole&&index.column()==0)
return QIcon("images/fold.png");

// 显示节点数据值
if(role==Qt::DisplayRole)

TreeItem *item=static_cast<TreeItem*>(index.internalPointer());
return item->data(index.column());


return QVariant();


Qt::ItemFlags TagTreeModel::flags(const QModelIndex &index) const

if(!index.isValid())
return 0;

return Qt::ItemIsEnabledQt::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(!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 TagTreeModel::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 TagTreeModel::rowCount(const QModelIndex &parent) const

TreeItem *parentItem;

if(!parent.isValid())
parentItem=rootItem;
else
parentItem=static_cast<TreeItem*>(parent.internalPointer());

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));


QTreeView - 排序和过滤模型

【中文标题】QTreeView - 排序和过滤模型【英文标题】:QTreeView - Sort and Filter a model 【发布时间】:2009-06-30 08:42:21 【问题描述】:

我正在尝试创建一个显示一些排序信息的 QTreeView。为此,我在视图和模型之间使用了 QSortFilterProxyModel。

问题是我想将行数限制为前 n 行(排序后)。模型中的过滤器函数接收原始的 sourceRow,所以我不能使用它。

我尝试链接两个 QSortFilterProxyModel:第一个用于排序,第二个用于过滤。但似乎第二个代理模型(过滤)没有收到排序的行......

还有其他方法吗? 有没有人使用这种技术(链接 2 个代理模型)并且有效?

谢谢

编辑: 我已经尝试使用 rowCount 并且它不起作用。 我也尝试链接 2 个代理模型,但问题是视图调用它接收的模型的排序函数。因此,如果第一个代理排序和第二个过滤器排序将在过滤器模型上调用并且数据不会被排序。

EDIT2:我查看了 qt 源代码,过滤是在排序之前完成的,所以在 filterAcceptsRow() 中我不知道任何排序顺序。

【问题讨论】:

你有没有试过在qtcentre.org上提问? 【参考方案1】:

只是出于好奇,您是否尝试过覆盖 rowCount 方法并仅返回 25(或任何 n 在您的情况下)?它可能就这么简单......好吧,如果你总是至少有 n 个项目。

否则,您可以尝试链接模型。我不知道为什么它不起作用,但我自己从未尝试过类似的东西。

【讨论】:

【参考方案2】:

在尝试了一些过于复杂的方法来解决这个问题后,我为我的问题做了一个小技巧:插入/删除一行后,我调用 setRowHidden 来隐藏前 n 行。 这不是最优雅的解决方案,并且特别适合我的需求,但我无法找到更好的替代方案。

我喜欢在 gtk 上提到这一点,因为过滤器和排序代理模型是分开的,这可以很容易地完成。

我仍然希望有人可以为此提供更好的解决方案。

【讨论】:

以上是关于谁熟悉QTreeView+QAbstractItemModel 多选删除功能的主要内容,如果未能解决你的问题,请参考以下文章

谁再说不熟悉 Linux 命令,就把这个给他扔过去

谁再说不熟悉 Linux 命令,就把这个给他扔过去

谁再说不熟悉 Linux 命令,就把这个给他扔过去

QTreeView

谁再说不熟悉Linux命令,就把这个给他扔过去!

右键单击 QTreeView 内的 QHeaderView