1, QSortFilterProxyModel
QSortFilterProxyModel is the agent of the model and cannot be used alone. The real data needs to be provided by another model. Its function is to sort and filter the proxy model (source model). The so-called filtering, that is, filtering the data according to the content you enter, because its filtering function is based on regular expressions, so it is powerful.
Now let's take a look at the basic usage of QSortFilterProxyModel from the two demo s of Qt - basicsortfiltermodel and customsortfiltermodel:
Proxymodel->setsourcemodel (model) is used to set which model is proxied
Proxymodel->setsortcasesensitivity (qt:: casesensitive) is used to set whether sorting is case sensitive
Proxymodel->setfilterkeycolumn (0) is used to specify the currently filtered column, and the parameter is the column number
Proxymodel->setfilterregexp (regexp) is used to set the filtering rules during filtering. The parameter type is QRegExp. The prototype of QRegExp is as follows:
explicit QRegExp(const QString &pattern, Qt::CaseSensitivity cs = Qt::CaseSensitive, PatternSyntax syntax = RegExp);
The first parameter is an expression, the second parameter indicates whether to distinguish case in the expression, and the third parameter is enum type, as shown below
enum PatternSyntax { RegExp, Wildcard, FixedString, RegExp2, WildcardUnix, W3CXmlSchema11 };
enum lists several types of regular expressions. Regular expressions have their own set of relatively general syntax, but for different language environments (such as Java, C# and Python), their specific definitions may be slightly different. Here we use Qt's own regular expression processing tool. The first QregExp::RegExp provides the most general regular expression syntax, but this syntax does not support greedy qualifiers, which is also the default rule of Qt. If you need to use the greedy qualifier, you need to use QRegExp::RegExp2. Second, we provide a common rule of Unix shell, which uses wildcard processing. The third is fixed expression, that is, regular expressions are basically not used. The first three are used in the demo
In customsortfiltermodel, you can subclass QSortFilterProxyModel and rewrite its lessThan and filterAcceptsRow methods to realize custom sorting and filtering. For details, please refer to the implementation of MySortFilterProxyModel class in customsortfiltermodel. It should be noted that if the filtering method changes, for example, from filtering column 1 to filtering column 2, you need to call the invalidefilter() function to invalidate the previous filtering and activate the current filtering
2, Using QSortFilterProxyModel in QML
1.source model uses QML built-in model
Here, the built-in ListModel of QML and the customized PageSortFilterProxyModel are used to turn pages. The effect is as follows
There are 110 black squares in total, and their ID numbers are displayed in the squares, with a maximum of 20 (pageSize) displayed each time. The squares displayed each time are filtered through the change of page (pageIndex). filterAcceptsRow is as follows:
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; }
Because the page number changes, you should call invalidefilter() every time you set the page number
void PageSortFilterProxyModel::setPageIndex(int index) { m_pageIndex = index; emit pageIndexChanged(); invalidateFilter(); }
It should be noted that the roleNames() method of QSortFilterProxyModel must be rewritten here, otherwise, after the ListModel is added to the PageSortFilterProxyModel, the elements in the ListModel cannot be used, and * * * is not defined error will be reported
QHash<int, QByteArray> PageSortFilterProxyModel::roleNames() const { return sourceModel()->roleNames(); }
The complete source code is as follows:
PageSortFilterProxyModel.h
#ifndef PAGESORTFILTERPROXYMODEL_H #define PAGESORTFILTERPROXYMODEL_H #include <QSortFilterProxyModel> class PageSortFilterProxyModel: public QSortFilterProxyModel { Q_OBJECT Q_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(); // Change to return leftdata. Toint() >rightdata. Toint(); The opposite result can be obtained // In fact, you can call lessThan of the parent class directly here. The above code is to demonstrate custom sorting // 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.0 import PageModel 1.0 Window { visible: true width: 640 height: 480 title: qsTr("Hello World") Item { anchors.fill: parent Column{ anchors.fill: parent Rectangle{ id: page property int pageSize: 20 property int pageIndex: 0 property int pageCount: gridModel.count % pageSize === 0 ? gridModel.count / pageSize : gridModel.count / pageSize + 1 property int sortOrder: Qt.AscendingOrder width: parent.width height: parent.height - 60 ListModel { id: gridModel } Grid{ anchors.centerIn: parent spacing: 10 columns: 5 Repeater{ model: PageModel{ sourceModel: gridModel pageIndex: page.pageIndex pageSize: page.pageSize sortOrder: page.sortOrder } delegate: Rectangle{ width: 100 height: 80 border.width: 1 color: "black" radius: 4 Text{ text: userID color: "white" anchors.centerIn: parent font.pixelSize: 20 } } } } Component.onCompleted: { for(var i=0; i<110; i++){ gridModel.append({"userID": i}) } } } Item{ width: parent.width height: 60 Row{ anchors.centerIn: parent spacing: 20 Button{ text: "Previous" width: 70 height: 40 onClicked: { if(page.pageIndex > 0) page.pageIndex -= 1 } } Text{ text: String(page.pageIndex + 1) + "/" + String(page.pageCount) anchors.verticalCenter: parent.verticalCenter } Button{ text: "Next" width: 70 height: 40 onClicked: { 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 use custom model
The customized model is inherited from QAbstractListModel. For how to customize the model, please refer to Qt official demo - contact list
Here, the user-defined model and the user-defined SearchSortFilterProxyModel are used to realize the search, and the effect is as follows:
As can be seen from the rendering, the list has 1000 lines, each of which includes user ID and user name. We will sort by user ID and filter (search) by user name
First, set the role s corresponding to user ID and user name in the customized QHListModel
enum Roles { IDRole = Qt::UserRole + 1, NameRole = Qt::UserRole + 2 };
Then call the setSortRole and setFilterRole methods of SearchSortFilterProxyModel to specify the roles used for sorting and filtering
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);
Finally, in lessThan and filterAcceptsRow, the data in the source model (QHListModel) is retrieved according to the role for sorting and filtering
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(); }
The complete source code is as follows:
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_OBJECT Q_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::RegExp); setFilterRegExp(regExp); }
main.cpp
#include <QGuiApplication> #include <QQmlApplicationEngine> #include <QQmlContext> #include "QHListModel.h" #include "SearchSortFilterProxyModel.h" #pragma execution_character_set("utf-8") // Random generator inline void DataBaseRoll(std::string &name) { //Hundred Surnames - single surname std::string NA1[444] = { "Zhao", "money", "Sun", "Li", "week", "Wu", "Zheng", "king", "Feng", "Chen", "Chu", "Wei", "a surname", "Shen", "Han", "Yang", "Zhu", "Qin", "especially", "Xu", "What", "LV", "Apply", "Zhang", "hole", "Cao", "strict", "Hua", "gold", "Wei", "pottery", "ginger", "Qi", "thank", "Zou", "Metaphor", "Cypress", "water", "sinus", "chapter", "cloud", "Soviet", "Pan", "arrowroot", "Xi", "Fan", "Peng", "Lang", "Lu", "Wei", "Chang", "horse", "seedling", "phoenix", "flower", "square", "a surname", "let", "Yuan", "Willow", "Feng", "abalone", "history", "Tang", "fee", "Incorruptible", "Cen", "Xue", "thunder", "Congratulations", "Ni", "soup", "Teng", "Yin", "Luo", "Finish", "Hao", "Wu", "security", "often", "happy", "to", "Hour", "Fu", "skin", "Bian", "Qi", "Kang", "five", "more than", "element", "Divination", "Gu", "Meng", "flat", "yellow", "and", "Mu", "Xiao", "Yin", "a surname", "Shao", "Zhan", "Woof", "Qi", "hair", "Yu", "Di", "rice", "shellfish", "bright", "Zang", "meter", "Volt", "become", "wear", "talk", "Song Dynasty", "Mao", "Pang", "bear", "Period", "Shu", "Bend", "term", "wish", "Dong", "beam", "Du", "Ruan", "blue", "Min", "seat", "season", "hemp", "strong", "Jia", "road", "Lou", "dangerous", "river", "child", "Face", "outer wall or surrounding area of a city", "plum blossom", "Sheng", "Forest", "Diao", "clock", "Xu", "Qiu", "Luo", "high", "summer", "CAI", "field", "Fan", "Hu", "Ling", "Huo", "Yu", "ten thousand", "branch", "Ke", "Surname", "Tube", "Lu", "no", "through", "room", "Fur", "Miao", "dry", "solution", "answer", "Zong", "Ding", "Publicize", "Cardia", "Deng", "Depression", "single", "Hang", "flood", "package", "various", "Left", "stone", "Cui", "luck", "button", "Gong", "Cheng", "Ji", "in place names", "slip", "Pei", "land", "Rong", "Weng", "a kind of fragrant grass", "sheep", "On", "benefit", "Zhen", "yeast", "home", "seal", "Rui", "name of a master archer", "Store", "Jin", "Draw", "Bing", "Mi", "pine", "well", "paragraph", "rich", "witch", "Wu", "coke", "Bar", "arch", "Herding", "Kui", "mountain", "valley", "vehicle", "Hou", "Mi", "Peng", "whole", "a surname", "class", "Look up", "autumn", "Zhong", "Yi", "The Palace", "Ning", "Hatred", "Luan", "Violent", "Gan", "Slant", "Fierce", "Rong", "Ancestor", "martial", "symbol", "Liu", "view", "Zhan", "beam", "Loong", "leaf", "Fortunately", "department", "Shao", "a surname", "Li", "Thistle", "thin", "print", "Overnight", "white", "Conceive", "Cattail", "Tai", "from", "Hubei", "Rope", "salty", "Nationality", "Lai", "Zhuo", "Lin", "Butcher", "Mongolia","pool", "Joe", "Yin", "Depression", "Xu", "can", "Cang", "double", "smell", "Shen", "party", "Zhai", "Tan", "Tribute", "work", "Pang", "woman", "Shen", "Help", "wall", "Ran", "Slaughter", "Li", "Yong", "saline soil", "Pangolin", "mulberry", "Cinnamon", "Pu", "cattle", "longevity", "through", "edge", "retinue", "Swallow", "Ji", "Jia", "Pu", "still", "agriculture", "temperature", "other", "Zhuang", "Yan", "firewood", "Qu", "Yan", "charge", "Admire", "even", "Ru", "Learn", "Official", "AI", "fish", "Rong", "towards", "ancient", "easy", "Cautious", "Ge", "Liao", "Yu", "end", "and", "House", "Balance", "step", "all", "Geng", "full", "Hong", "Kuang", "country", "writing", "Kou", "wide", "prosperity", "Que", "east", "Beat", "Be careful", "Wo", "benefit", "Wei", "Yue", "Kui", "Long", "division", "Sclera", "She", "Nie", "Chao", "Tick", "Ao", "melt", "cold", "Zi", "Xin", "a surname", "that", "simple", "Rao", "empty", "once", "No", "sand", "What", "raise", "Ju", "must", "Abundant", "nest", "shut", "Kuai", "mutually", "check", "After", "Wattle", "red", "swim", "Zhu", "power", "Lu", "cover", "benefit", "Huan", "common", "be in charge of", "Governor", "Jin", "Chu", "a surname", "method", "Ru", "Yan", "apply", "Qin", "return", "sea","Yue", "Handsome", "Gout", "Hyperactivity", "condition", "after", "have", "Piano", "merchant", "Mou", "She", "Nie", "Bo", "Reward", "ink", "Ha", "Qiao", "Da", "year", "love", "Yang", "Tong", "word", "blessing" }; std::string NA2[59] = { "Wanqi", "Sima", "Shangguan", "Ouyang", "Xia Hou", "Zhuge", "Wen Ren", "east", "Helian", "Huangfu", "Yuchi", "Ram", "Dan Tai", "Gongye", "Patriarchal government", "Puyang", "Chunyu", "Shan Yu", "Uncle Tai", "Shentu", "Gongsun", "Zhongsun", "Xuanyuan", "Linghu", "Zhong Li", "Yuwen", "eldest grandson", "Murong", "Fresh in", "Lu Qiu", "Situ", "Sikong", "Qi Guan", "Sikou", "Sub car", "Zhuansun", "Endwood", "Wuma", "Gongxi", "Lacquer carving", "Le Zheng", "Soil Si", "Gong Liang", "Tuoba", "Jiagu", "Kill the father", "Guliang", "Baili", "Dongguo", "South Gate", "Huyan", "Sheep tongue", "Microgenesis", "Liangqiu", "a two-character surname", "East Gate", "west gate", "Nangong", "fifth" }; std::string ME1m[140] = { "Wei", "Just.", "Brave", "Yi", "Handsome", "peak", "strong", "army", "flat", "protect", "east", "writing", "Brilliance", "power", "bright", "forever", "healthy", "life", "wide", "Annals", "righteousness", "Xing", "good", "sea", "mountain", "kernel", "wave", "Ning", "expensive", "blessing", "living", "Loong", "element", "whole", "country", "win", "learn", "Auspicious", "just", "hair", "martial", "new", "benefit", "clear", "fly", "Bin", "rich", "along", "letter", "son", "Jay", "Tao", "Chang", "become", "Kang", "Star", "light", "day", "reach", "security", "rock", "in", "Luxuriant", "enter", "Forest", "have", "Firm", "and", "Biao", "Bo", "Sincerity", "before", "respect", "earthquake", "Vibration", "strong", "meeting", "thinking", "group", "Howe", "heart", "state", "Undertake", "happy", "Shao", "Work", "pine", "good", "thick", "Celebrate", "Lei", "civil", "friend", "Abundant", "river", "Philosophy", "river", "exceed", "Hao", "bright", "politics", "Modest", "Heng", "odd", "solid", "of", "round", "Han", "Lang", "Bo", "macro", "word", "if", "Chirp", "Friend", "Bin", "beam", "Building", "dimension", "Start", "gram", "Lun", "Soar", "Xu", "Peng", "Ze", "morning", "Chen", "Scholar", "with", "build", "home", "To", "tree", "inflammation", "virtue", "that 's ok", "Hour", "Tai", "Sheng" }; std::string ME1f[165] = { "Show", "Juan", "Britain", "Hua", "Wisdom", "Skillfully", "beautiful", "Na", "quiet", "Shu", "benefit", "bead", "Emerald", "Elegant", "Ganoderma lucidum", "Jade", "Ping", "red", "E", "Ling", "Fen", "Aromatic", "Swallow", "color", "spring", "chrysanthemum", "orchid", "phoenix", "clean", "plum blossom", "Lin", "element", "cloud", "lotus", "really", "ring", "snow", "Rong", "love", "Sister", "Rosy clouds", "fragrant", "month", "Warbler", "Yuan", "Gorgeous", "Rui", "all", "good", "Jia", "Joan", "Diligent", "Jane", "Zhen", "Li", "Cinnamon", "Di", "leaf", "BI", "Lu", "Ya", "Qi", "crystal", "Yan", "Qian", "autumn", "Shan", "Sha", "Brocade", "Dai", "young", "Qian", "Ting", "Jiao", "Euphemism", "Xian", "Jin", "Glume", "dew", "Yao", "Yi", "Chan", "Wild goose", "Bud", "Wan", "instrument", "Lotus", "Dan", "Rong", "eyebrow", "Jun", "Piano", "Stamen", "Wei", "Cyanine", "dream", "Haze", "Garden", "Yun", "soft", "bamboo", "Mist", "Coagulate", "Xiao", "Joyous", "Xiao", "Maple", "Yun", "phenanthrene", "cold", "Hin", "crystal-clear", "Yi", "Sub", "should", "can", "woman", "Shu", "shadow", "Litchi", "branch", "thinking", "Li", "Show", "Floating", "Nurture", "Fu", "Qi", "crystal", "Yan", "Qian", "autumn", "Shan", "Sha", "Brocade", "Dai", "young", "Qian", "Ting", "Ning","Bud", "Wan", "Garden", "Jie", "Sweet", "Yuan", "a kind of jade", "rhyme", "melt", "garden", "art", "Chant", "Qing", "Cong", "LAN", "pure", "Yu", "Joy", "Zhao", "ice", "Cool", "Wan", "Tea", "plume", "Hope" }; std::string sex = (rand()%2 == 0?"male":"female");//Men and women choose name = (rand()%56 != 5?NA1[rand()%444]:NA2[rand()%59]);//Single surname Or multiple surname selection name += (sex == "male" ? ME1m[rand()%140] : ME1f[rand()%165]);//Name the first word if(rand()%2 == 0) name += (sex == "male" ? ME1m[rand()%140] : ME1f[rand()%165]);//Name the second word } 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.0 Window { visible: true width: 480 height: 800 title: qsTr("Hello World") Item { anchors.fill: parent anchors.margins: 10 Rectangle { id: searchTool anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right height: 40 RowLayout { anchors.fill: parent anchors.centerIn: parent TextField { placeholderText: "Please enter keywords" Layout.fillWidth: true font.pointSize: 12 onTextChanged: { searchModel.filterString = text; } } CheckBox { text: "DescendingOrder" onCheckedChanged:{ searchModel.sortOrder = checked ? Qt.DescendingOrder : Qt.AscendingOrder; } } } } ListView { id: view model: searchModel anchors.top: searchTool.bottom anchors.topMargin: 3 anchors.bottom: parent.bottom anchors.left: parent.left anchors.right: parent.right cacheBuffer: 100 clip: true spacing: 1 delegate: Rectangle{ width: parent.width radius: 5 anchors.horizontalCenter: parent.horizontalCenter height: 40 color: "black" RowLayout { anchors.fill: parent anchors.leftMargin: 30 spacing: 30 Text { text: userID font.pointSize: 12 font.bold: true color: "white" } Text { text: userName font.pointSize: 12 font.bold: true color: "white" Layout.fillWidth: true } } } ScrollBar.vertical: ScrollBar { anchors.right: parent.right anchors.rightMargin: 1 width: 16 } } } }
Original link: https://blog.csdn.net/caoshangpa/article/details/126021903