一.QSortFilterProxyModel

QSortFilterProxyModel是model的代理,不能单独使用,真正的数据需要另外的一个model提供,它的功能是对被代理的model(source model)进行排序和过滤。所谓过滤,也就是说按照你输入的内容进行数据的筛选,因为其过滤功能是基于正则表达式的,所以功能强大。
我们现从Qt自带的两个demo——basicsortfiltermodel和customsortfiltermodel来看看QSortFilterProxyModel的基本使用方法:


proxyModel->setSourceModel(model)用于设置哪个model被代理
proxyModel->setSortCaseSensitivity(Qt::CaseSensitive)用来设置排序时是否区分大小写
proxyModel->setFilterKeyColumn(0)用来指定当前过滤的列,参数为列号
proxyModel->setFilterRegExp(regExp)用于设置过滤时的筛选规则,参数类型为QRegExp,QRegExp的原型如下:

explicit QRegExp(const QString &pattern, Qt::CaseSensitivity cs = Qt::CaseSensitive,PatternSyntax syntax = RegExp);

第一个参数是表达式,第二个参数表示是否区分表达式中的大小写,第三个参数是enum类型,如下所示

enum PatternSyntax {RegExp,Wildcard,FixedString,RegExp2,WildcardUnix,W3CXmlSchema11 };

enum中罗列了正则表达式的几种类型。正则表达式自己有一套相对通用的语法,但是对于不同的语言环境(例如 Java、C# 和 Python),其具体定义可能会略有差别。这里我们使用的是Qt自己的正则表达式处理工具。第一个 QregExp::RegExp提供了最一般的正则表达式语法,但这个语法不支持贪婪限定符,这也是Qt 默认的规则。如果需要使用贪婪限定符,需要使用 QRegExp::RegExp2。第二个我们提供的是Unix shell常见的一种规则,使用通配符处理。第三个即固定表达式,也就是说基本上不使用正则表达式。demo中使用的就是前三种


customsortfiltermodel中通过子类化QSortFilterProxyModel,重写其lessThan和filterAcceptsRow方法来实现自定义的排序和过滤,具体可参考customsortfiltermodel中MySortFilterProxyModel类的实现。需要注意的是,如果过滤方式改变了,比如从过滤第1列变成了过滤第2列,需要调用invalidateFilter()函数,使之前的过滤失效,激活当前过滤

二.在QML中使用QSortFilterProxyModel

1.source model使用QML内置model

这里使用QML内置的ListModel,加上自定义的PageSortFilterProxyModel来实现翻页,效果如下所示

一共有110个黑色方块,方块中显示其ID号,每次最多显示20个(pageSize),通过页面(pageIndex)的变化来过滤每次显示的方块,filterAcceptsRow如下:

bool PageSortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{Q_UNUSED(sourceParent)int min = m_pageSize * m_pageIndex;int max = m_pageSize * m_pageIndex + m_pageSize;return sourceRow >= min && sourceRow < max;
}

因为页码是变化的,因此每次设置完页码后都要调用invalidateFilter()

void PageSortFilterProxyModel::setPageIndex(int index)
{m_pageIndex = index;emit pageIndexChanged();invalidateFilter();
}

需要注意的是,这里必须重写QSortFilterProxyModel的roleNames()方法,否则在ListModel添加到PageSortFilterProxyModel后,ListModel中的元素就无法使用了,会报*** is not defined错误

QHash<int, QByteArray> PageSortFilterProxyModel::roleNames() const
{return sourceModel()->roleNames();
}

完整源码如下:
PageSortFilterProxyModel.h

#ifndef PAGESORTFILTERPROXYMODEL_H
#define PAGESORTFILTERPROXYMODEL_H#include <QSortFilterProxyModel>class PageSortFilterProxyModel: public QSortFilterProxyModel
{Q_OBJECTQ_PROPERTY(int pageIndex READ pageIndex WRITE setPageIndex NOTIFY pageIndexChanged)Q_PROPERTY(int pageSize READ pageSize WRITE setPageSize NOTIFY pageSizeChanged)Q_PROPERTY(int sortOrder READ sortOrder WRITE setSortOrder NOTIFY sortOrderChanged)public:PageSortFilterProxyModel(QObject *parent = nullptr);~PageSortFilterProxyModel();int pageSize() const;void setPageSize(int size);int pageIndex() const;void setPageIndex(int index);int sortOrder() const;void setSortOrder(int order);signals:void pageIndexChanged();void pageSizeChanged();void sortOrderChanged();protected:QHash<int, QByteArray> roleNames() const override;bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;private:int m_pageIndex;int m_pageSize;int m_sortOrder = Qt::AscendingOrder;
};#endif // PAGESORTFILTERPROXYMODEL_H

PageSortFilterProxyModel.cpp

#include "PageSortFilterProxyModel.h"
#include <QDebug>
PageSortFilterProxyModel::PageSortFilterProxyModel(QObject *parent): QSortFilterProxyModel (parent)
{}PageSortFilterProxyModel::~PageSortFilterProxyModel()
{}QHash<int, QByteArray> PageSortFilterProxyModel::roleNames() const
{return sourceModel()->roleNames();
}bool PageSortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{Q_UNUSED(sourceParent)int min = m_pageSize * m_pageIndex;int max = m_pageSize * m_pageIndex + m_pageSize;return sourceRow >= min && sourceRow < max;
}bool PageSortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
{QVariant leftData = sourceModel()->data(left);QVariant rightData = sourceModel()->data(right);return leftData.toInt()<rightData.toInt();// 改成return leftData.toInt()>rightData.toInt();可得到相反的结果.// 这里其实直接调用父类的lessThan就行,上述代码中是为了演示自定义排序.// return QSortFilterProxyModel::lessThan(left, right);
}int PageSortFilterProxyModel::pageSize() const
{return m_pageSize;
}void PageSortFilterProxyModel::setPageSize(int size)
{m_pageSize = size;emit pageSizeChanged();
}int PageSortFilterProxyModel::pageIndex() const
{return m_pageIndex;
}void PageSortFilterProxyModel::setPageIndex(int index)
{m_pageIndex = index;emit pageIndexChanged();invalidateFilter();
}int PageSortFilterProxyModel::sortOrder() const
{return m_sortOrder;
}void PageSortFilterProxyModel::setSortOrder(int order)
{m_sortOrder = order;emit sortOrderChanged();sort(0,static_cast<Qt::SortOrder>(order));
}

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>#include "PageSortFilterProxyModel.h"int main(int argc, char *argv[])
{QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);QGuiApplication app(argc, argv);QQmlApplicationEngine engine;qmlRegisterType<PageSortFilterProxyModel>("PageModel", 1, 0, "PageModel");engine.load(QUrl(QStringLiteral("qrc:/main.qml")));if (engine.rootObjects().isEmpty())return -1;return app.exec();
}

main.qml

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.0import PageModel 1.0Window {visible: truewidth: 640height: 480title: qsTr("Hello World")Item {anchors.fill: parentColumn{anchors.fill: parentRectangle{id: pageproperty int pageSize: 20property int pageIndex: 0property int pageCount: gridModel.count % pageSize === 0 ? gridModel.count / pageSize : gridModel.count / pageSize + 1property int sortOrder: Qt.AscendingOrderwidth: parent.widthheight: parent.height - 60ListModel {id: gridModel}Grid{anchors.centerIn: parentspacing: 10columns: 5Repeater{model: PageModel{sourceModel: gridModelpageIndex: page.pageIndexpageSize: page.pageSizesortOrder: page.sortOrder}delegate: Rectangle{width: 100height: 80border.width: 1color: "black"radius: 4Text{text: userIDcolor: "white"anchors.centerIn: parentfont.pixelSize: 20}}}}Component.onCompleted: {for(var i=0; i<110; i++){gridModel.append({"userID": i})}}}Item{width: parent.widthheight: 60Row{anchors.centerIn: parentspacing: 20Button{text: "Previous"width: 70height: 40onClicked: {if(page.pageIndex > 0)page.pageIndex -= 1}}Text{text: String(page.pageIndex + 1) + "/" + String(page.pageCount)anchors.verticalCenter: parent.verticalCenter}Button{text: "Next"width: 70height: 40onClicked: {if(page.pageIndex < page.pageCount - 1)page.pageIndex += 1}}CheckBox {text: "DescendingOrder"onCheckedChanged:{if(checked){page.sortOrder = Qt.DescendingOrder}else{page.sortOrder = Qt.AscendingOrder}}}}}}}
}

2.source model使用自定义model

自定义的model继承自QAbstractListModel,如何自定义model,可参考Qt官方demo——contact list


这里使用自定义的model,加上自定义的SearchSortFilterProxyModel来实现搜索,效果如下所示:


从效果图中可以看到,列表有1000行,每行都包括用户ID和用户名,我们将使用用户ID进行排序,使用用户名进行过滤(搜索)
首先要在自定义的QHListModel中分别设置用户ID和用户名对应的role

enum Roles
{IDRole = Qt::UserRole + 1,NameRole = Qt::UserRole + 2
};

接着在调用SearchSortFilterProxyModel的setSortRole和setFilterRole方法来指定排序和过滤所使用的role

QHListModel listModel;for(int i=0;i<1000;i++)
{std::string name;DataBaseRoll(name);QString userName = QString::fromStdString(name);QString userID = QString::number(i);listModel.addData(userID,userName);
}SearchSortFilterProxyModel searchModel;
searchModel.setSourceModel(&listModel);
searchModel.setSortRole(IDRole);
searchModel.setFilterRole(NameRole);

最后在lessThan和filterAcceptsRow中根据role取出source model(QHListModel)中的数据进行排序和过滤

bool SearchSortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);return sourceModel()->data(index, filterRole()).toString().contains(filterRegExp());
}bool SearchSortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
{QVariant leftData = sourceModel()->data(left, sortRole());QVariant rightData = sourceModel()->data(right, sortRole());return leftData.toInt()<rightData.toInt();
}

完整源码如下:
QHListModel.h

#ifndef QHLISTMODEL_H
#define QHLISTMODEL_H#include <QAbstractListModel>enum Roles
{IDRole = Qt::UserRole + 1,NameRole = Qt::UserRole + 2
};class QHListModel : public QAbstractListModel
{
public:QHListModel();~QHListModel();void addData(const QString &id, const QString &name);protected:int rowCount(const QModelIndex &parent = QModelIndex()) const override;QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;QHash<int, QByteArray> roleNames() const override;private:QStringList m_userIDs;QStringList m_userNames;
};#endif // QHLISTMODEL_H

QHListModel.cpp

#include "QHListModel.h"QHListModel::QHListModel()
{}QHListModel::~QHListModel()
{}void QHListModel::addData(const QString &id, const QString &name)
{beginInsertRows(QModelIndex(), rowCount(), rowCount());m_userIDs.append(id);m_userNames.append(name);endInsertRows();
}int QHListModel::rowCount(const QModelIndex &parent) const
{Q_UNUSED(parent)return m_userNames.count();
}QVariant QHListModel::data(const QModelIndex &index, int role) const
{if (index.row() < 0 || index.row() >= m_userNames.count()){return QVariant();}if (role == IDRole){return m_userIDs[index.row()];}if (role == NameRole){return m_userNames[index.row()];}return QVariant();
}QHash<int, QByteArray> QHListModel::roleNames() const
{QHash<int, QByteArray> roles;roles[IDRole] = "userID";roles[NameRole] = "userName";return roles;
}

SearchSortFilterProxyModel.h

#ifndef SEARCHSORTFILTERPROXYMODEL_H
#define SEARCHSORTFILTERPROXYMODEL_H#include <QSortFilterProxyModel>class SearchSortFilterProxyModel: public QSortFilterProxyModel
{Q_OBJECTQ_PROPERTY(int sortOrder READ sortOrder WRITE setSortOrder NOTIFY sortOrderChanged)Q_PROPERTY(QString filterString READ filterString WRITE setFilterString NOTIFY filterStringChanged)public:SearchSortFilterProxyModel(QObject *parent = nullptr);~SearchSortFilterProxyModel();int sortOrder() const;void setSortOrder(int order);QString filterString() const;void setFilterString(const QString &string);signals:void sortOrderChanged();void filterStringChanged();protected:QHash<int, QByteArray> roleNames() const override;bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;private:int m_sortOrder = Qt::AscendingOrder;QString m_filterString;
};#endif // SEARCHSORTFILTERPROXYMODEL_H

SearchSortFilterProxyModel.cpp

#include "SearchSortFilterProxyModel.h"#include <QDebug>
#include <QRegExp>SearchSortFilterProxyModel::SearchSortFilterProxyModel(QObject *parent): QSortFilterProxyModel (parent)
{}SearchSortFilterProxyModel::~SearchSortFilterProxyModel()
{}QHash<int, QByteArray> SearchSortFilterProxyModel::roleNames() const
{return sourceModel()->roleNames();
}bool SearchSortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);return sourceModel()->data(index, filterRole()).toString().contains(filterRegExp());
}bool SearchSortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
{QVariant leftData = sourceModel()->data(left, sortRole());QVariant rightData = sourceModel()->data(right, sortRole());return leftData.toInt()<rightData.toInt();
}int SearchSortFilterProxyModel::sortOrder() const
{return m_sortOrder;
}void SearchSortFilterProxyModel::setSortOrder(int order)
{m_sortOrder = order;emit sortOrderChanged();sort(0,static_cast<Qt::SortOrder>(order));
}QString SearchSortFilterProxyModel::filterString() const
{return m_filterString;
}void SearchSortFilterProxyModel::setFilterString(const QString &string)
{m_filterString = string;emit filterStringChanged();QRegExp regExp(string, Qt::CaseSensitive, QRegExp::FixedString);setFilterRegExp(regExp);
}

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>#include "QHListModel.h"
#include "SearchSortFilterProxyModel.h"#pragma execution_character_set("utf-8")// 随机民生成器.
inline void DataBaseRoll(std::string &name)
{//百家姓-单姓.std::string NA1[444] = { "赵", "钱", "孙", "李", "周", "吴", "郑", "王", "冯", "陈", "褚", "卫", "蒋", "沈", "韩", "杨", "朱", "秦", "尤", "许", "何", "吕", "施", "张", "孔", "曹", "严", "华", "金", "魏", "陶", "姜", "戚", "谢", "邹", "喻", "柏", "水", "窦", "章", "云", "苏", "潘", "葛", "奚", "范", "彭", "郎", "鲁", "韦", "昌", "马", "苗", "凤", "花", "方", "俞", "任", "袁", "柳", "酆", "鲍", "史", "唐", "费", "廉", "岑", "薛", "雷", "贺", "倪", "汤", "滕", "殷", "罗", "毕", "郝", "邬", "安", "常", "乐", "于", "时", "傅", "皮", "卞", "齐", "康", "伍", "余", "元", "卜", "顾", "孟", "平", "黄", "和", "穆", "萧", "尹", "姚", "邵", "湛", "汪", "祁", "毛", "禹", "狄", "米", "贝", "明", "臧", "计", "伏", "成", "戴", "谈", "宋", "茅", "庞", "熊", "纪", "舒", "屈", "项", "祝", "董", "梁", "杜", "阮", "蓝", "闵", "席", "季", "麻", "强", "贾", "路", "娄", "危", "江", "童", "颜", "郭", "梅", "盛", "林", "刁", "钟", "徐", "邱", "骆", "高", "夏", "蔡", "田", "樊", "胡", "凌", "霍", "虞", "万", "支", "柯", "昝", "管", "卢", "莫", "经", "房", "裘", "缪", "干", "解", "应", "宗", "丁", "宣", "贲", "邓", "郁", "单", "杭", "洪", "包", "诸", "左", "石", "崔", "吉", "钮", "龚", "程", "嵇", "邢", "滑", "裴", "陆", "荣", "翁", "荀", "羊", "於", "惠", "甄", "麴", "家", "封", "芮", "羿", "储", "靳", "汲", "邴", "糜", "松", "井", "段", "富", "巫", "乌", "焦", "巴", "弓", "牧", "隗", "山", "谷", "车", "侯", "宓", "蓬", "全", "郗", "班", "仰", "秋", "仲", "伊", "宫", "宁", "仇", "栾", "暴", "甘", "钭", "厉", "戎", "祖", "武", "符", "刘", "景", "詹", "束", "龙", "叶", "幸", "司", "韶", "郜", "黎", "蓟", "薄", "印", "宿", "白", "怀", "蒲", "邰", "从", "鄂", "索", "咸", "籍", "赖", "卓", "蔺", "屠", "蒙","池", "乔", "阴", "郁", "胥", "能", "苍", "双", "闻", "莘", "党", "翟", "谭", "贡", "劳", "逄", "姬", "申", "扶", "堵", "冉", "宰", "郦", "雍", "舄", "璩", "桑", "桂", "濮", "牛", "寿", "通", "边", "扈", "燕", "冀", "郏", "浦", "尚", "农", "温", "别", "庄", "晏", "柴", "瞿", "阎", "充", "慕", "连", "茹", "习", "宦", "艾", "鱼", "容", "向", "古", "易", "慎", "戈", "廖", "庾", "终", "暨", "居", "衡", "步", "都", "耿", "满", "弘", "匡", "国", "文", "寇", "广", "禄", "阙", "东", "殴", "殳", "沃", "利", "蔚", "越", "夔", "隆", "师", "巩", "厍", "聂", "晁", "勾", "敖", "融", "冷", "訾", "辛", "阚", "那", "简", "饶", "空", "曾", "毋", "沙", "乜", "养", "鞠", "须", "丰", "巢", "关", "蒯", "相", "查", "後", "荆", "红", "游", "竺", "权", "逯", "盖", "益", "桓", "公", "仉", "督", "晋", "楚", "闫", "法", "汝", "鄢", "涂", "钦", "归", "海","岳", "帅", "缑", "亢", "况", "后", "有", "琴", "商", "牟", "佘", "佴", "伯", "赏", "墨", "哈", "谯", "笪", "年", "爱", "阳", "佟", "言", "福" };std::string NA2[59] = { "万俟", "司马", "上官", "欧阳", "夏侯", "诸葛", "闻人", "东方", "赫连", "皇甫", "尉迟", "公羊", "澹台", "公冶", "宗政", "濮阳", "淳于", "单于", "太叔", "申屠", "公孙", "仲孙", "轩辕", "令狐", "钟离", "宇文", "长孙", "慕容", "鲜于", "闾丘", "司徒", "司空", "亓官", "司寇", "子车", "颛孙", "端木", "巫马", "公西", "漆雕", "乐正", "壤驷", "公良", "拓跋", "夹谷", "宰父", "谷梁", "百里", "东郭", "南门", "呼延", "羊舌", "微生", "梁丘", "左丘", "东门", "西门", "南宫", "第五" };std::string ME1m[140] = { "伟", "刚", "勇", "毅", "俊", "峰", "强", "军", "平", "保", "东", "文", "辉", "力", "明", "永", "健", "世", "广", "志", "义", "兴", "良", "海", "山", "仁", "波", "宁", "贵", "福", "生", "龙", "元", "全", "国", "胜", "学", "祥", "才", "发", "武", "新", "利", "清", "飞", "彬", "富", "顺", "信", "子", "杰", "涛", "昌", "成", "康", "星", "光", "天", "达", "安", "岩", "中", "茂", "进", "林", "有", "坚", "和", "彪", "博", "诚", "先", "敬", "震", "振", "壮", "会", "思", "群", "豪", "心", "邦", "承", "乐", "绍", "功", "松", "善", "厚", "庆", "磊", "民", "友", "裕", "河", "哲", "江", "超", "浩", "亮", "政", "谦", "亨", "奇", "固", "之", "轮", "翰", "朗", "伯", "宏", "言", "若", "鸣", "朋", "斌", "梁", "栋", "维", "启", "克", "伦", "翔", "旭", "鹏", "泽", "晨", "辰", "士", "以", "建", "家", "致", "树", "炎", "德", "行", "时", "泰", "盛" };std::string ME1f[165] = { "秀", "娟", "英", "华", "慧", "巧", "美", "娜", "静", "淑", "惠", "珠", "翠", "雅", "芝", "玉", "萍", "红", "娥", "玲", "芬", "芳", "燕", "彩", "春", "菊", "兰", "凤", "洁", "梅", "琳", "素", "云", "莲", "真", "环", "雪", "荣", "爱", "妹", "霞", "香", "月", "莺", "媛", "艳", "瑞", "凡", "佳", "嘉", "琼", "勤", "珍", "贞", "莉", "桂", "娣", "叶", "璧", "璐", "娅", "琦", "晶", "妍", "茜", "秋", "珊", "莎", "锦", "黛", "青", "倩", "婷", "姣", "婉", "娴", "瑾", "颖", "露", "瑶", "怡", "婵", "雁", "蓓", "纨", "仪", "荷", "丹", "蓉", "眉", "君", "琴", "蕊", "薇", "菁", "梦", "岚", "苑", "筠", "柔", "竹", "霭", "凝", "晓", "欢", "霄", "枫", "芸", "菲", "寒", "欣", "滢", "伊", "亚", "宜", "可", "姬", "舒", "影", "荔", "枝", "思", "丽", "秀", "飘", "育", "馥", "琦", "晶", "妍", "茜", "秋", "珊", "莎", "锦", "黛", "青", "倩", "婷", "宁","蓓", "纨", "苑", "婕", "馨", "瑗", "琰", "韵", "融", "园", "艺", "咏", "卿", "聪", "澜", "纯", "毓", "悦", "昭", "冰", "爽", "琬", "茗", "羽", "希" };std::string sex = (rand()%2 == 0?"男":"女");//男女选择.name = (rand()%56 != 5?NA1[rand()%444]:NA2[rand()%59]);//单姓Or复姓选择.name += (sex == "男" ? ME1m[rand()%140] : ME1f[rand()%165]);//取名第一字.if(rand()%2 == 0) name += (sex == "男" ? ME1m[rand()%140] : ME1f[rand()%165]);//取名第二字.
}int main(int argc, char *argv[])
{QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);QGuiApplication app(argc, argv);QHListModel listModel;for(int i=0;i<1000;i++){std::string name;DataBaseRoll(name);QString userName = QString::fromStdString(name);QString userID = QString::number(i);listModel.addData(userID,userName);}SearchSortFilterProxyModel searchModel;searchModel.setSourceModel(&listModel);searchModel.setSortRole(IDRole);searchModel.setFilterRole(NameRole);QQmlApplicationEngine engine;QQmlContext *context = engine.rootContext();context->setContextProperty("searchModel", &searchModel);engine.load(QUrl(QStringLiteral("qrc:/main.qml")));if (engine.rootObjects().isEmpty())return -1;return app.exec();
}

main.qml

import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0Window {visible: truewidth: 480height: 800title: qsTr("Hello World")Item {anchors.fill: parentanchors.margins: 10Rectangle {id: searchToolanchors.top: parent.topanchors.left: parent.leftanchors.right: parent.rightheight: 40RowLayout {anchors.fill: parentanchors.centerIn: parentTextField {placeholderText: "请输入关键字"Layout.fillWidth: truefont.pointSize: 12onTextChanged: {searchModel.filterString = text;}}CheckBox {text: "DescendingOrder"onCheckedChanged:{searchModel.sortOrder = checked ? Qt.DescendingOrder : Qt.AscendingOrder;}}}}ListView {id: viewmodel: searchModelanchors.top: searchTool.bottomanchors.topMargin: 3anchors.bottom: parent.bottomanchors.left: parent.leftanchors.right: parent.rightcacheBuffer: 100clip: truespacing: 1delegate: Rectangle{width: parent.widthradius: 5anchors.horizontalCenter: parent.horizontalCenterheight: 40color: "black"RowLayout {anchors.fill: parentanchors.leftMargin: 30spacing: 30Text {text: userIDfont.pointSize: 12font.bold: truecolor: "white"}Text {text: userNamefont.pointSize: 12font.bold: truecolor: "white"Layout.fillWidth: true}}}ScrollBar.vertical: ScrollBar {anchors.right: parent.rightanchors.rightMargin: 1width: 16}}}
}

原文链接:https://blog.csdn.net/caoshangpa/article/details/126021903

QML中使用QSortFilterProxyModel进行排序和过滤相关推荐

  1. mysql 如何对表排序_学习MySQL:对表中的数据进行排序和过滤

    mysql 如何对表排序 In this article, we will learn how we can sort and filter data using the WHERE clause a ...

  2. QSortFilterProxyModel实现排序、过滤

    1. QSortFilterProxyModel介绍 QSortFilterProxyModel类用来为model和view之间提供强大的排序和过滤支持.将模型排序或者过滤后在视图上显示,并且无需对模 ...

  3. Java集合或Map中元素排序及过滤

    在Java中,对集合或Map中元素进行排序或过滤是一个频繁操作.这里以List为例介绍下如何在集合中实现元素的排序和过滤功能.对于非List元素(Set.Map)等,一方面可以参考List使用类似的方 ...

  4. 【EntityFramework系列教程三,翻译】在ASP.NET MVC程序中使用EntityFramework对数据进行排序、过滤筛选以及实现分页...

    上一章中您已经为Students实体集实现了不同页面的增删改查的功能,本章中您将为Index页面给Students增加分页.过滤以及排序功能.你将创建一个实现简单分组功能的页面. 以下就是即将你要看到 ...

  5. html 表格过滤功能,简单的带排序和过滤功能的jQuery表格插件

    smart-table是一款简单实用的带排序和过滤功能的jQuery表格插件.该jQuery表格插件通过简单的设置就可以生成表格排序.表格字段过滤功能,甚至可以实现表格分页显示,使用非常方便. 使用方 ...

  6. Compass 更智能的搜索引擎(3)--高亮,排序,过滤以及各种搜索

    要想使得一个搜索系统更加的完美,查询精确度和页面显示算是其中比较重要的两个方面.今天,我们就来谈谈怎么使得我们的搜索系统更加的完美. 关于分词 下载地址 配置 关于高亮 关于排序 原理 冗余字段 使用 ...

  7. mysql 排序 过滤_【MYSQL】-3 排序与过滤

    上周加入数据蛙二期培训,结束了孤独战斗的现状.断断续续自学了3个月(当然看了各种视频和各种书,一把辛酸泪...),现在选择报班,主要还是觉得一个靠谱的组织和团队,可以极大缓解我学习过程中不时闪现的焦虑 ...

  8. Contoso 大学 - 3 - 排序、过滤及分页

    原文地址:http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/sorting-filtering-and-paging ...

  9. Android 实现ListView的A-Z字母排序和过滤搜索功能,实现汉字转成拼音

    转载请注明出处:http://blog.csdn.net/xiaanming/article/details/12684155 前段时间因为换工作的缘故又恰巧碰到国庆节,所以有段时间自己没有更新博客了 ...

  10. Android 使用RecyclerView实现(仿微信)的联系人A-Z字母排序和过滤搜索功能

    之前做项目的时候遇到一个需求是实现品牌的字母排序功能,网上的资料很多,但是有一部分有bug,这篇文章是我学习和解决部分bug之后的总结.今天带来的是RecyclerView的A-Z字母排序和过滤搜索功 ...

最新文章

  1. org.springframework.security.web.util.TextEscapeUtils
  2. 【8-23】MFC学习笔记 01
  3. Spring-Aop-注解实现
  4. 53、shell常用快捷方式
  5. Redis模式对比:主从模式 VS 哨兵sentinel模式 VS Redis cluster模式
  6. 我的596升级到Windows Mobile 6了
  7. 硅谷新一代媒体巨头Mode Media突然宣布关闭
  8. 安装ps时无法验证订阅状态_免费申请office E5开发者订阅,附无限续期+私人网盘教程...
  9. AOJ 0525 Osenbei
  10. 课程 3: Content Providers 简介
  11. 代码修改之后MSbuild编译不出最新的dll解决方法
  12. 探访IBM企业级区块链-CSDN公开课-专题视频课程
  13. pymol作图-输出PNG格式图片
  14. Thesus(忒修斯)的故事
  15. h5 invoke android,uniapp安卓版本11.0.0以上真机调试App: onLaunch have been invoked
  16. 二维码图片生成工具C#winform源码
  17. 【Unity】StreamingAssets和PersistentData文件夹
  18. 镜面反射与Phong模型
  19. [CV] 基于机器视觉和强化学习的导航
  20. 自建视频流媒体服务器需要满足哪些条件?

热门文章

  1. Cadence学习之路:寻找优秀的封装资源以及3D封装设置
  2. 【精讲版】上位机C#/.NET与西门子PLC通信
  3. overleaf 公式_Latex的公式输入
  4. 一款免费且强大的gif动画录制工具,再也不愁录动画!
  5. RS-232通信接口
  6. udhcpc 的使用
  7. 如何使用Git SVN工具 -- TortoiseGit(小乌龟)将本地项目上传至GitEE?【超详细教程】
  8. java方法重载的好处_Java方法重载浅谈
  9. 一个编辑的黑洞项目:编程日历背后的 “鬼级操作”
  10. ass字幕转换成文本文件