• Qt之在QML中使用QSortFilterProxyModel进行排序和过滤


    一.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的原型如下:

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

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

    1. enum PatternSyntax {
    2.     RegExp,
    3.     Wildcard,
    4.     FixedString,
    5.     RegExp2,
    6.     WildcardUnix,
    7.     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如下:

    1. bool PageSortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
    2. {
    3.     Q_UNUSED(sourceParent)
    4.     int min = m_pageSize * m_pageIndex;
    5.     int max = m_pageSize * m_pageIndex + m_pageSize;
    6.     return sourceRow >= min && sourceRow < max;
    7. }

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

    1. void PageSortFilterProxyModel::setPageIndex(int index)
    2. {
    3.     m_pageIndex = index;
    4.     emit pageIndexChanged();
    5.     invalidateFilter();
    6. }

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

    1. QHash<int, QByteArray> PageSortFilterProxyModel::roleNames() const
    2. {
    3.     return sourceModel()->roleNames();
    4. }

    完整源码如下:
    PageSortFilterProxyModel.h

    1. #ifndef PAGESORTFILTERPROXYMODEL_H
    2. #define PAGESORTFILTERPROXYMODEL_H
    3. #include
    4. class PageSortFilterProxyModel: public QSortFilterProxyModel
    5. {
    6. Q_OBJECT
    7. Q_PROPERTY(int pageIndex READ pageIndex WRITE setPageIndex NOTIFY pageIndexChanged)
    8. Q_PROPERTY(int pageSize READ pageSize WRITE setPageSize NOTIFY pageSizeChanged)
    9. Q_PROPERTY(int sortOrder READ sortOrder WRITE setSortOrder NOTIFY sortOrderChanged)
    10. public:
    11. PageSortFilterProxyModel(QObject *parent = nullptr);
    12. ~PageSortFilterProxyModel();
    13. int pageSize() const;
    14. void setPageSize(int size);
    15. int pageIndex() const;
    16. void setPageIndex(int index);
    17. int sortOrder() const;
    18. void setSortOrder(int order);
    19. signals:
    20. void pageIndexChanged();
    21. void pageSizeChanged();
    22. void sortOrderChanged();
    23. protected:
    24. QHash<int, QByteArray> roleNames() const override;
    25. bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
    26. bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
    27. private:
    28. int m_pageIndex;
    29. int m_pageSize;
    30. int m_sortOrder = Qt::AscendingOrder;
    31. };
    32. #endif // PAGESORTFILTERPROXYMODEL_H

    PageSortFilterProxyModel.cpp

    1. #include "PageSortFilterProxyModel.h"
    2. #include
    3. PageSortFilterProxyModel::PageSortFilterProxyModel(QObject *parent)
    4. : QSortFilterProxyModel (parent)
    5. {
    6. }
    7. PageSortFilterProxyModel::~PageSortFilterProxyModel()
    8. {
    9. }
    10. QHash<int, QByteArray> PageSortFilterProxyModel::roleNames() const
    11. {
    12. return sourceModel()->roleNames();
    13. }
    14. bool PageSortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
    15. {
    16. Q_UNUSED(sourceParent)
    17. int min = m_pageSize * m_pageIndex;
    18. int max = m_pageSize * m_pageIndex + m_pageSize;
    19. return sourceRow >= min && sourceRow < max;
    20. }
    21. bool PageSortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
    22. {
    23. QVariant leftData = sourceModel()->data(left);
    24. QVariant rightData = sourceModel()->data(right);
    25. return leftData.toInt()toInt();
    26. // 改成return leftData.toInt()>rightData.toInt();可得到相反的结果.
    27. // 这里其实直接调用父类的lessThan就行,上述代码中是为了演示自定义排序.
    28. // return QSortFilterProxyModel::lessThan(left, right);
    29. }
    30. int PageSortFilterProxyModel::pageSize() const
    31. {
    32. return m_pageSize;
    33. }
    34. void PageSortFilterProxyModel::setPageSize(int size)
    35. {
    36. m_pageSize = size;
    37. emit pageSizeChanged();
    38. }
    39. int PageSortFilterProxyModel::pageIndex() const
    40. {
    41. return m_pageIndex;
    42. }
    43. void PageSortFilterProxyModel::setPageIndex(int index)
    44. {
    45. m_pageIndex = index;
    46. emit pageIndexChanged();
    47. invalidateFilter();
    48. }
    49. int PageSortFilterProxyModel::sortOrder() const
    50. {
    51. return m_sortOrder;
    52. }
    53. void PageSortFilterProxyModel::setSortOrder(int order)
    54. {
    55. m_sortOrder = order;
    56. emit sortOrderChanged();
    57. sort(0,static_cast(order));
    58. }

    main.cpp

    1. #include
    2. #include
    3. #include "PageSortFilterProxyModel.h"
    4. int main(int argc, char *argv[])
    5. {
    6. QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    7. QGuiApplication app(argc, argv);
    8. QQmlApplicationEngine engine;
    9. qmlRegisterType("PageModel", 1, 0, "PageModel");
    10. engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    11. if (engine.rootObjects().isEmpty())
    12. return -1;
    13. return app.exec();
    14. }

    main.qml

    1. import QtQuick 2.9
    2. import QtQuick.Window 2.2
    3. import QtQuick.Controls 2.0
    4. import PageModel 1.0
    5. Window {
    6. visible: true
    7. width: 640
    8. height: 480
    9. title: qsTr("Hello World")
    10. Item {
    11. anchors.fill: parent
    12. Column{
    13. anchors.fill: parent
    14. Rectangle{
    15. id: page
    16. property int pageSize: 20
    17. property int pageIndex: 0
    18. property int pageCount: gridModel.count % pageSize === 0 ? gridModel.count / pageSize : gridModel.count / pageSize + 1
    19. property int sortOrder: Qt.AscendingOrder
    20. width: parent.width
    21. height: parent.height - 60
    22. ListModel {
    23. id: gridModel
    24. }
    25. Grid{
    26. anchors.centerIn: parent
    27. spacing: 10
    28. columns: 5
    29. Repeater{
    30. model: PageModel{
    31. sourceModel: gridModel
    32. pageIndex: page.pageIndex
    33. pageSize: page.pageSize
    34. sortOrder: page.sortOrder
    35. }
    36. delegate: Rectangle{
    37. width: 100
    38. height: 80
    39. border.width: 1
    40. color: "black"
    41. radius: 4
    42. Text{
    43. text: userID
    44. color: "white"
    45. anchors.centerIn: parent
    46. font.pixelSize: 20
    47. }
    48. }
    49. }
    50. }
    51. Component.onCompleted: {
    52. for(var i=0; i<110; i++){
    53. gridModel.append({"userID": i})
    54. }
    55. }
    56. }
    57. Item{
    58. width: parent.width
    59. height: 60
    60. Row{
    61. anchors.centerIn: parent
    62. spacing: 20
    63. Button{
    64. text: "Previous"
    65. width: 70
    66. height: 40
    67. onClicked: {
    68. if(page.pageIndex > 0)
    69. page.pageIndex -= 1
    70. }
    71. }
    72. Text{
    73. text: String(page.pageIndex + 1) + "/" + String(page.pageCount)
    74. anchors.verticalCenter: parent.verticalCenter
    75. }
    76. Button{
    77. text: "Next"
    78. width: 70
    79. height: 40
    80. onClicked: {
    81. if(page.pageIndex < page.pageCount - 1)
    82. page.pageIndex += 1
    83. }
    84. }
    85. CheckBox {
    86. text: "DescendingOrder"
    87. onCheckedChanged:{
    88. if(checked){
    89. page.sortOrder = Qt.DescendingOrder
    90. }else{
    91. page.sortOrder = Qt.AscendingOrder
    92. }
    93. }
    94. }
    95. }
    96. }
    97. }
    98. }
    99. }

    2.source model使用自定义model

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


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


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

    1. enum Roles
    2. {
    3.     IDRole = Qt::UserRole + 1,
    4.     NameRole = Qt::UserRole + 2
    5. };

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

    1. QHListModel listModel;
    2. for(int i=0;i<1000;i++)
    3. {
    4.     std::string name;
    5.     DataBaseRoll(name);
    6.     
    7.     QString userName = QString::fromStdString(name);
    8.     QString userID = QString::number(i);
    9.     
    10.     listModel.addData(userID,userName);
    11. }
    12. SearchSortFilterProxyModel searchModel;
    13. searchModel.setSourceModel(&listModel);
    14. searchModel.setSortRole(IDRole);
    15. searchModel.setFilterRole(NameRole);

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

    1. bool SearchSortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
    2. {
    3.     QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
    4.     return sourceModel()->data(index, filterRole()).toString().contains(filterRegExp());
    5. }
    6. bool SearchSortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
    7. {
    8.     QVariant leftData = sourceModel()->data(left, sortRole());
    9.     QVariant rightData = sourceModel()->data(right, sortRole());
    10.     return leftData.toInt()
    11. }

    完整源码如下:
    QHListModel.h

    1. #ifndef QHLISTMODEL_H
    2. #define QHLISTMODEL_H
    3. #include
    4. enum Roles
    5. {
    6. IDRole = Qt::UserRole + 1,
    7. NameRole = Qt::UserRole + 2
    8. };
    9. class QHListModel : public QAbstractListModel
    10. {
    11. public:
    12. QHListModel();
    13. ~QHListModel();
    14. void addData(const QString &id, const QString &name);
    15. protected:
    16. int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    17. QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    18. QHash<int, QByteArray> roleNames() const override;
    19. private:
    20. QStringList m_userIDs;
    21. QStringList m_userNames;
    22. };
    23. #endif // QHLISTMODEL_H

    QHListModel.cpp

    1. #include "QHListModel.h"
    2. QHListModel::QHListModel()
    3. {
    4. }
    5. QHListModel::~QHListModel()
    6. {
    7. }
    8. void QHListModel::addData(const QString &id, const QString &name)
    9. {
    10. beginInsertRows(QModelIndex(), rowCount(), rowCount());
    11. m_userIDs.append(id);
    12. m_userNames.append(name);
    13. endInsertRows();
    14. }
    15. int QHListModel::rowCount(const QModelIndex &parent) const
    16. {
    17. Q_UNUSED(parent)
    18. return m_userNames.count();
    19. }
    20. QVariant QHListModel::data(const QModelIndex &index, int role) const
    21. {
    22. if (index.row() < 0 || index.row() >= m_userNames.count())
    23. {
    24. return QVariant();
    25. }
    26. if (role == IDRole)
    27. {
    28. return m_userIDs[index.row()];
    29. }
    30. if (role == NameRole)
    31. {
    32. return m_userNames[index.row()];
    33. }
    34. return QVariant();
    35. }
    36. QHash<int, QByteArray> QHListModel::roleNames() const
    37. {
    38. QHash<int, QByteArray> roles;
    39. roles[IDRole] = "userID";
    40. roles[NameRole] = "userName";
    41. return roles;
    42. }

    SearchSortFilterProxyModel.h

    1. #ifndef SEARCHSORTFILTERPROXYMODEL_H
    2. #define SEARCHSORTFILTERPROXYMODEL_H
    3. #include
    4. class SearchSortFilterProxyModel: public QSortFilterProxyModel
    5. {
    6. Q_OBJECT
    7. Q_PROPERTY(int sortOrder READ sortOrder WRITE setSortOrder NOTIFY sortOrderChanged)
    8. Q_PROPERTY(QString filterString READ filterString WRITE setFilterString NOTIFY filterStringChanged)
    9. public:
    10. SearchSortFilterProxyModel(QObject *parent = nullptr);
    11. ~SearchSortFilterProxyModel();
    12. int sortOrder() const;
    13. void setSortOrder(int order);
    14. QString filterString() const;
    15. void setFilterString(const QString &string);
    16. signals:
    17. void sortOrderChanged();
    18. void filterStringChanged();
    19. protected:
    20. QHash<int, QByteArray> roleNames() const override;
    21. bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
    22. bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
    23. private:
    24. int m_sortOrder = Qt::AscendingOrder;
    25. QString m_filterString;
    26. };
    27. #endif // SEARCHSORTFILTERPROXYMODEL_H

    SearchSortFilterProxyModel.cpp

    1. #include "SearchSortFilterProxyModel.h"
    2. #include
    3. #include
    4. SearchSortFilterProxyModel::SearchSortFilterProxyModel(QObject *parent)
    5. : QSortFilterProxyModel (parent)
    6. {
    7. }
    8. SearchSortFilterProxyModel::~SearchSortFilterProxyModel()
    9. {
    10. }
    11. QHash<int, QByteArray> SearchSortFilterProxyModel::roleNames() const
    12. {
    13. return sourceModel()->roleNames();
    14. }
    15. bool SearchSortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
    16. {
    17. QModelIndex index = sourceModel()->index(sourceRow, 0, sourceParent);
    18. return sourceModel()->data(index, filterRole()).toString().contains(filterRegExp());
    19. }
    20. bool SearchSortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
    21. {
    22. QVariant leftData = sourceModel()->data(left, sortRole());
    23. QVariant rightData = sourceModel()->data(right, sortRole());
    24. return leftData.toInt()
    25. }
    26. int SearchSortFilterProxyModel::sortOrder() const
    27. {
    28. return m_sortOrder;
    29. }
    30. void SearchSortFilterProxyModel::setSortOrder(int order)
    31. {
    32. m_sortOrder = order;
    33. emit sortOrderChanged();
    34. sort(0,static_cast(order));
    35. }
    36. QString SearchSortFilterProxyModel::filterString() const
    37. {
    38. return m_filterString;
    39. }
    40. void SearchSortFilterProxyModel::setFilterString(const QString &string)
    41. {
    42. m_filterString = string;
    43. emit filterStringChanged();
    44. QRegExp regExp(string, Qt::CaseSensitive, QRegExp::FixedString);
    45. setFilterRegExp(regExp);
    46. }

    main.cpp

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

    main.qml

    1. import QtQuick 2.9
    2. import QtQuick.Window 2.2
    3. import QtQuick.Controls 2.0
    4. import QtQuick.Layouts 1.0
    5. Window {
    6. visible: true
    7. width: 480
    8. height: 800
    9. title: qsTr("Hello World")
    10. Item {
    11. anchors.fill: parent
    12. anchors.margins: 10
    13. Rectangle {
    14. id: searchTool
    15. anchors.top: parent.top
    16. anchors.left: parent.left
    17. anchors.right: parent.right
    18. height: 40
    19. RowLayout {
    20. anchors.fill: parent
    21. anchors.centerIn: parent
    22. TextField {
    23. placeholderText: "请输入关键字"
    24. Layout.fillWidth: true
    25. font.pointSize: 12
    26. onTextChanged: {
    27. searchModel.filterString = text;
    28. }
    29. }
    30. CheckBox {
    31. text: "DescendingOrder"
    32. onCheckedChanged:{
    33. searchModel.sortOrder = checked ? Qt.DescendingOrder : Qt.AscendingOrder;
    34. }
    35. }
    36. }
    37. }
    38. ListView {
    39. id: view
    40. model: searchModel
    41. anchors.top: searchTool.bottom
    42. anchors.topMargin: 3
    43. anchors.bottom: parent.bottom
    44. anchors.left: parent.left
    45. anchors.right: parent.right
    46. cacheBuffer: 100
    47. clip: true
    48. spacing: 1
    49. delegate: Rectangle{
    50. width: parent.width
    51. radius: 5
    52. anchors.horizontalCenter: parent.horizontalCenter
    53. height: 40
    54. color: "black"
    55. RowLayout {
    56. anchors.fill: parent
    57. anchors.leftMargin: 30
    58. spacing: 30
    59. Text {
    60. text: userID
    61. font.pointSize: 12
    62. font.bold: true
    63. color: "white"
    64. }
    65. Text {
    66. text: userName
    67. font.pointSize: 12
    68. font.bold: true
    69. color: "white"
    70. Layout.fillWidth: true
    71. }
    72. }
    73. }
    74. ScrollBar.vertical: ScrollBar {
    75. anchors.right: parent.right
    76. anchors.rightMargin: 1
    77. width: 16
    78. }
    79. }
    80. }
    81. }

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

  • 相关阅读:
    frp内网穿透实战
    redis启动命令
    弹性数据库连接池探活策略调研(二)——Druid
    挑战杯 基于GRU的 电影评论情感分析 - python 深度学习 情感分类
    MYSQL数据库-基础概念
    libtorch c++ 定义全链接网络
    NSFC申请不中的反思 (内部讨论)
    dubbo+zookeeper的使用
    结合实战,浅析GB/T28181(四)——录像回放及控制
    电脑系统修复,操作简单
  • 原文地址:https://blog.csdn.net/caoshangpa/article/details/126021903