在树视图中过滤模型项
Filter model items in tree view
我有一个模型class:
class ItemModel : public QAbstractItemModel
{
Q_OBJECT
public:
enum ItemRoles {
ItemRole = Qt::UserRole + 1,
NameRole,
IdRole,
FilterRole // To be used in filtering
};
QVariant data(const QModelIndex &index, int role) const;
}
根据角色建模returns数据:
QVariant ItemModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
Item *item = itemFromIndex(index);
switch (role) {
case ItemRole:
return QVariant::fromValue(item);
case NameRole:
return QVariant::fromValue(item->entity()->objectName());
case IdRole:
return QVariant::fromValue(item->entity()->id().id());
case FilterRole:
{
switch (item->itemTask()) {
case Item::ItemTask::ToBeFiltered:
return QVariant::fromValue(QString("yes"));
default:
return QVariant::fromValue(QString("no"));
}
}
default:
return QVariant();
}
}
我使用父 class 的 QSortFilterProxyModel
成员来过滤我的模型:
class ParentClass : public QObject
{
Q_OBJECT
Q_PROPERTY(ItemModel * sceneModel READ sceneModel CONSTANT)
Q_PROPERTY(QSortFilterProxyModel * sceneModelProxy READ sceneModelProxy CONSTANT)
private:
ItemModel *m_sceneModel;
QSortFilterProxyModel *m_sceneModelProxy;
}
QSortFilterProxyModel
在父 class 构造函数中设置:
ParentClass::ParentClass(QObject *parent)
: QObject(parent)
, m_sceneModel(new ItemModel(this))
, m_sceneModelProxy(new QSortFilterProxyModel())
{
// Proxy to filter out unwanted items from tree-view of model
// Looks into a specific role for each item,
// if data value returned for that role passes the regexp, then include item in proxy model
m_sceneModelProxy->setFilterRole(ItemModel::ItemRoles::FilterRole);
m_sceneModelProxy->setFilterRegExp("^no$");
m_sceneModelProxy->setSourceModel(m_sceneModel);
}
Parent class 注册为 QML 类型并在 QML 上使用:
ParentClass {
id: parentClass
}
现在在 QML 上,我使用 TreeView
类型来显示模型:
TreeView {
model: parentClass.sceneModel
selection: ItemSelectionModel {
model: parentClass.sceneModel
}
style: TreeViewStyle { // ... }
itemDelegate: FocusScope { // ... }
TableViewColumn { role: "name" }
}
TreeView
中有 相当多的 逻辑,这取决于 parentClass.sceneModel
。我用 parentClass.sceneModelProxy
.
替换了所有 parentClass.sceneModel
个实例
没有任何代理的原始树视图工作正常:
应用代理后,树视图为空:
我花了一些时间来调试 QSortFilterProxyModel
用法。有人可以给我提示吗?
尝试设置 m_sceneModelProxy->setDynamicSortFilter(true)
或在设置后调用 m_sceneModelProxy->invalidate()
一次。
在运行应用程序的时候查看Qt Creator日志,无意间注意到了这个日志:
QMetaProperty::read: Unable to handle unregistered datatype 'QSortFilterProxyModel*' for property 'ParentClass_QML_193::sceneModelProxy'
我通过 a suggested approach 注册 QSortFilterProxyModel*
指针解决了上面的日志:
#include <QSortFilterProxyModel>
qRegisterMetaType<QSortFilterProxyModel*>("QSortFilterProxyModel*");
现在 QML TreeView
可以正确过滤掉不需要的项目 =)
我有一个模型class:
class ItemModel : public QAbstractItemModel
{
Q_OBJECT
public:
enum ItemRoles {
ItemRole = Qt::UserRole + 1,
NameRole,
IdRole,
FilterRole // To be used in filtering
};
QVariant data(const QModelIndex &index, int role) const;
}
根据角色建模returns数据:
QVariant ItemModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
Item *item = itemFromIndex(index);
switch (role) {
case ItemRole:
return QVariant::fromValue(item);
case NameRole:
return QVariant::fromValue(item->entity()->objectName());
case IdRole:
return QVariant::fromValue(item->entity()->id().id());
case FilterRole:
{
switch (item->itemTask()) {
case Item::ItemTask::ToBeFiltered:
return QVariant::fromValue(QString("yes"));
default:
return QVariant::fromValue(QString("no"));
}
}
default:
return QVariant();
}
}
我使用父 class 的 QSortFilterProxyModel
成员来过滤我的模型:
class ParentClass : public QObject
{
Q_OBJECT
Q_PROPERTY(ItemModel * sceneModel READ sceneModel CONSTANT)
Q_PROPERTY(QSortFilterProxyModel * sceneModelProxy READ sceneModelProxy CONSTANT)
private:
ItemModel *m_sceneModel;
QSortFilterProxyModel *m_sceneModelProxy;
}
QSortFilterProxyModel
在父 class 构造函数中设置:
ParentClass::ParentClass(QObject *parent)
: QObject(parent)
, m_sceneModel(new ItemModel(this))
, m_sceneModelProxy(new QSortFilterProxyModel())
{
// Proxy to filter out unwanted items from tree-view of model
// Looks into a specific role for each item,
// if data value returned for that role passes the regexp, then include item in proxy model
m_sceneModelProxy->setFilterRole(ItemModel::ItemRoles::FilterRole);
m_sceneModelProxy->setFilterRegExp("^no$");
m_sceneModelProxy->setSourceModel(m_sceneModel);
}
Parent class 注册为 QML 类型并在 QML 上使用:
ParentClass {
id: parentClass
}
现在在 QML 上,我使用 TreeView
类型来显示模型:
TreeView {
model: parentClass.sceneModel
selection: ItemSelectionModel {
model: parentClass.sceneModel
}
style: TreeViewStyle { // ... }
itemDelegate: FocusScope { // ... }
TableViewColumn { role: "name" }
}
TreeView
中有 相当多的 逻辑,这取决于 parentClass.sceneModel
。我用 parentClass.sceneModelProxy
.
parentClass.sceneModel
个实例
没有任何代理的原始树视图工作正常:
应用代理后,树视图为空:
我花了一些时间来调试 QSortFilterProxyModel
用法。有人可以给我提示吗?
尝试设置 m_sceneModelProxy->setDynamicSortFilter(true)
或在设置后调用 m_sceneModelProxy->invalidate()
一次。
在运行应用程序的时候查看Qt Creator日志,无意间注意到了这个日志:
QMetaProperty::read: Unable to handle unregistered datatype 'QSortFilterProxyModel*' for property 'ParentClass_QML_193::sceneModelProxy'
我通过 a suggested approach 注册 QSortFilterProxyModel*
指针解决了上面的日志:
#include <QSortFilterProxyModel>
qRegisterMetaType<QSortFilterProxyModel*>("QSortFilterProxyModel*");
现在 QML TreeView
可以正确过滤掉不需要的项目 =)