Qt uses QSortFilterProxyModel to sort and filter in QML

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

Tags: search engine Qt Permutation qml

Posted by grga on Sat, 06 Aug 2022 02:33:25 +0930