如何避免在qml中将列表模型中的列表元素添加到ListView [英] How to avoid a list element in a list model from being added to ListView in qml
问题描述
我有一个 ListModel
:
ListModel {
id: sourceModel
ListElement { sourceType: "Christian's Galexy"; sourceName: "Bluetooth"; visible: true }
ListElement { sourceType: "BBC Radio"; sourceName: "DAB"; visible: true }
ListElement { sourceType: "Media Library"; sourceName: ""; visible: false }
ListElement { sourceType: "Chris's Music"; sourceName: "USB"; visible: false }
}
我有一个 ListView
:
ListView {
id: source_list
width: parent.width; height: parent.height
spacing: 6
model: sourceModel
delegate: sourceDelegate
focus: true
interactive: true
clip: true
boundsBehavior: Flickable.StopAtBounds
}
我只想膨胀可见属性为 true 的 ListElement
.我不想夸大 ListView
中的其他列表元素.我怎样才能做到这一点?
I only want to inflate ListElement
which has visible attribute as true. I don't want to inflate the other list elements in the ListView
.
How can I achieve this?
推荐答案
另一种解决方案是使用 QSortFilterProxyModel
真正过滤项目,而不仅仅是隐藏它们.例如:
Another solution is to use QSortFilterProxyModel
which really filters item, not just hides them. For example:
FilterModel.h
class FilterModel : public QSortFilterProxyModel
{
Q_OBJECT
Q_PROPERTY(QByteArray filterRole READ filterRole WRITE setFilterRole NOTIFY filterRoleChanged)
public:
FilterModel(QObject *parent = Q_NULLPTR);
QByteArray filterRole() const;
void setFilterRole(const QByteArray roleName);
protected:
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const Q_DECL_OVERRIDE;
private:
QByteArray m_filterRole;
signals:
void filterRoleChanged();
};
FilterModel.cpp
FilterModel::FilterModel(QObject *parent) :
QSortFilterProxyModel(parent)
{}
QByteArray FilterModel::filterRole() const
{
return m_filterRole;
}
void FilterModel::setFilterRole(const QByteArray roleName)
{
if(roleName != m_filterRole) {
m_filterRole = roleName;
emit filterRoleChanged();
}
}
bool FilterModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
{
QModelIndex index = sourceModel()->index(source_row, 0, source_parent);
int role = sourceModel()->roleNames().key(m_filterRole,(int)Qt::DisplayRole);
QVariant data = index.data(role);
QVariant returnedValue;
QMetaObject::invokeMethod(const_cast<FilterModel *>(this), "filter",
Q_RETURN_ARG(QVariant, returnedValue),
Q_ARG(QVariant, data));
return returnedValue.toBool();
}
为了使过滤器灵活,它使用 FilterModel
项目中的 Javascript 函数对项目进行排序.
To make the filter flexible it uses Javascript function from FilterModel
item to sort items.
所以用法是:
ListModel {
id: listModel
ListElement { name: "name1"; visible: true }
ListElement { name: "name2"; visible: true }
ListElement { name: "name3"; visible: false }
ListElement { name: "name4"; visible: true }
}
FilterModel {
id: proxyModel
sourceModel: listModel
filterRole: "visible"
function filter(value)
{
return value;
}
}
ListView {
model: proxyModel
anchors.fill: parent
spacing: 2
delegate: Rectangle {
height: 30;
width: parent.width
border{ width: 1; color: "#999" }
color: "#DEDEDE"
Text {
anchors { centerIn: parent; margins: 5 }
text: name
verticalAlignment: Text.AlignVCenter
}
}
}
所有的魔法都发生在 FilterModel.filter()
中.它应该只返回 false
以跳过项目.
All the magic takes place in FilterModel.filter()
. It should just return false
to skip an item.
这篇关于如何避免在qml中将列表模型中的列表元素添加到ListView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!