• Qt文档阅读笔记-Fetch More Example解析


    Fetch More Example这个例子说明了如何在视图模型上添加记录。

    这个例子由一个对话框组成,在Directory的输入框中,可输入路径信息。应用程序会载入路径信息的文件信息等。不需要按回车键就能搜索。

    当有大量数据时,需要对视图模型进行批量增加。

    此案例,实现了FileListModel类,此类包含了一个视图模型,这个视图模型获取路径下的文件。

    下面来看下FileListModel的代码。

    FileListModel Class Definition

    FileListModel继承了QAbstractListModel并且存储了路径信息。只有视图自己请求添加项时,才会进行添加。

    1. class FileListModel : public QAbstractListModel
    2. {
    3. Q_OBJECT
    4. public:
    5. FileListModel(QObject *parent = 0);
    6. int rowCount(const QModelIndex &parent = QModelIndex()) const override;
    7. QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    8. signals:
    9. void numberPopulated(int number);
    10. public slots:
    11. void setDirPath(const QString &path);
    12. protected:
    13. bool canFetchMore(const QModelIndex &parent) const override;
    14. void fetchMore(const QModelIndex &parent) override;
    15. private:
    16. QStringList fileList;
    17. int fileCount;
    18. };

    比较关键的2个函数是fetchMore()和canFetchMore(),这两个函数都是从QAbstractItemModel中继承下来的。当需要新增模型时,这2个函数就会被触发。

    setDirPath()函数设置了当前模型的工作目录。当需要批量设置模型时,就会发出numberPopulated()信号。

    所有文件条目都放到fileList里面,fileCount统计条目的数量。

    FileListModel Class Implementation

    首先来看下setDirPath()。

    1. void FileListModel::setDirPath(const QString &path)
    2. {
    3. QDir dir(path);
    4. beginResetModel();
    5. fileList = dir.entryList();
    6. fileCount = 0;
    7. endResetModel();
    8. }

    使用QDir获取目录内容。当要从模型中移除所有数据时需要通知QAbstractItemModel。

    1. bool FileListModel::canFetchMore(const QModelIndex & /* index */) const
    2. {
    3. if (fileCount < fileList.size())
    4. return true;
    5. else
    6. return false;
    7. }

    当需要更多项时,canFetchMore()函数会被触发。当不需要新增时此函数返回true,否则返回false。fetchMore()函数如下:

    1. void FileListModel::fetchMore(const QModelIndex & /* index */)
    2. {
    3. int remainder = fileList.size() - fileCount;
    4. int itemsToFetch = qMin(100, remainder);
    5. if (itemsToFetch <= 0)
    6. return;
    7. beginInsertRows(QModelIndex(), fileCount, fileCount+itemsToFetch-1);
    8. fileCount += itemsToFetch;
    9. endInsertRows();
    10. emit numberPopulated(itemsToFetch);
    11. }

    首先获取每一项的数量。beginInsertRow()和endInsertRow()在QAbstractItemModel中插入新行时,必须要调用的,最后emit numberPopulated()用于更新界面。

    最后是rowCount()和data()

    1. int FileListModel::rowCount(const QModelIndex & /* parent */) const
    2. {
    3. return fileCount;
    4. }
    5. QVariant FileListModel::data(const QModelIndex &index, int role) const
    6. {
    7. if (!index.isValid())
    8. return QVariant();
    9. if (index.row() >= fileList.size() || index.row() < 0)
    10. return QVariant();
    11. if (role == Qt::DisplayRole) {
    12. return fileList.at(index.row());
    13. } else if (role == Qt::BackgroundRole) {
    14. int batch = (index.row() / 100) % 2;
    15. if (batch == 0)
    16. return qApp->palette().base();
    17. else
    18. return qApp->palette().alternateBase();
    19. }
    20. return QVariant();
    21. }

    rowCount()函数是已经添加了的新行,不是目录中的条目数。

    data()函数,从fileList中返回适当的条目。使用不同的背景颜色来区分。

  • 相关阅读:
    springboot电气与信息类书籍网上书店 java ssm书籍借阅归还系统
    Animator动画状态机
    如何系列 如何玩转远程调用之OpenFegin+SpringBoot(非Cloud)
    学会 arthas,让你 3 年经验掌握 5 年功力!
    ICPC-2022网络赛第二场
    ModuleNotFoundError: No module named ‘requests‘
    drf重写authenticate方法实现多条件登录(源码分析)
    前端数据库大批量存,indexdDB使用
    设计模式之【适配器模式】
    Flink双流join导致数据重复
  • 原文地址:https://blog.csdn.net/qq78442761/article/details/134369267