文档章节

Qt Quick之ListView下拉刷新数据

41245110
 41245110
发布于 2015/06/05 21:41
字数 1237
阅读 160
收藏 1

Qt Quick里的ListView,本身是Flickable的派生类,当你用鼠标拖曳或者手指触摸(触摸屏)时,会产生flickStarted和flickEnded两个信号,利用这两个信号,就可以实现下拉刷新数据,当然上拉刷新也是可以的。

    创建一个Qt Quick App项目,添加dynamicModel.h和dynamicModel.cpp两个文件,用于实现DynamicListModel。项目创建过程参考《Qt Quick 之 Hello World 图文详解》。

    我们实现的下拉刷新效果有点儿特别,每次刷新后,只保留预定义的一页数据,比如代码中默认的页大小为20。

    版权所有foruok,转载请注明出处:http://blog.csdn.net/foruok

C++ model实现

    很简单,直接上代码了。

    dynamic.h:

[cpp] view plaincopy

  1. #ifndef DYNAMICMODEL_H  

  2. #define DYNAMICMODEL_H  

  3. #include <QAbstractListModel>  

  4.   

  5. class DynamicListModelPrivate;  

  6. class DynamicListModel : public QAbstractListModel  

  7. {  

  8.     Q_OBJECT  

  9.     Q_PROPERTY(int pageSize READ pageSize WRITE setPageSize NOTIFY pageSizeChanged)  

  10.     Q_PROPERTY(int total READ total WRITE setTotal NOTIFY totalChanged)  

  11. public:  

  12.     DynamicListModel(QObject *parent = 0);  

  13.     ~DynamicListModel();  

  14.   

  15.     int rowCount(const QModelIndex &parent) const;  

  16.     QVariant data(const QModelIndex &index, int role) const;  

  17.     QHash<int, QByteArray> roleNames() const;  

  18.   

  19.     Q_INVOKABLE void loadMore(bool forward);  

  20.   

  21.     int pageSize();  

  22.     void setPageSize(int size);  

  23.     int total();  

  24.     void setTotal(int total);  

  25.   

  26. signals:  

  27.     void pageSizeChanged(int size);  

  28.     void totalChanged(int total);  

  29.   

  30. private:  

  31.     DynamicListModelPrivate *m_dptr;  

  32. };  

  33.   

  34. #endif // DYNAMICMODEL_H  


    dynamicModel.cpp:

[cpp] view plaincopy

  1. #include "dynamicModel.h"  

  2. #include <QDebug>  

  3.   

  4. class DynamicListModelPrivate  

  5. {  

  6. public:  

  7.     DynamicListModelPrivate(DynamicListModel *model)  

  8.         : m_model(model), m_start(0), m_end(20)  

  9.         , m_total(100), m_pageSize(20)  

  10.     {  

  11.         m_roleNames.insert(Qt::UserRole, "content");  

  12.     }  

  13.   

  14.     void pageDown()  

  15.     {  

  16.         if(m_end < m_total)  

  17.         {  

  18.             m_start += m_pageSize;  

  19.             m_end += m_pageSize;  

  20.             if(m_end > m_total)  

  21.             {  

  22.                 m_end = m_total;  

  23.                 m_start = m_end - m_pageSize;  

  24.             }  

  25.         }  

  26.     }  

  27.   

  28.     void pageUp()  

  29.     {  

  30.         if(m_start > 0)  

  31.         {  

  32.             m_start -= m_pageSize;  

  33.             if(m_start < 0) m_start = 0;  

  34.             m_end = m_start + m_pageSize;  

  35.         }  

  36.     }  

  37.   

  38.     void adjustPageRange()  

  39.     {  

  40.         if(m_end - m_start < m_pageSize)  

  41.         {  

  42.             m_end = m_start + m_pageSize;  

  43.             if(m_end > m_total)  

  44.             {  

  45.                 m_end = m_total;  

  46.                 m_start = m_end - m_pageSize;  

  47.             }  

  48.         }  

  49.     }  

  50.   

  51.     DynamicListModel *m_model;  

  52.     int m_start;  

  53.     int m_end;  

  54.     int m_total;  

  55.     int m_pageSize;  

  56.     QHash<int, QByteArray> m_roleNames;  

  57. };  

  58.   

  59. DynamicListModel::DynamicListModel(QObject *parent)  

  60.     : QAbstractListModel(parent),  

  61.     m_dptr(new DynamicListModelPrivate(this))  

  62. {  

  63.   

  64. }  

  65.   

  66. DynamicListModel::~DynamicListModel()  

  67. {  

  68.     delete m_dptr;  

  69. }  

  70.   

  71. int DynamicListModel::rowCount(const QModelIndex &parent) const  

  72. {  

  73.     return m_dptr->m_end - m_dptr->m_start;  

  74. }  

  75.   

  76. QVariant DynamicListModel::data(const QModelIndex &index, int role) const  

  77. {  

  78.     int row = index.row();  

  79.     //qDebug() << "index.row - " << row << " start - " << m_dptr->m_start;  

  80.     return QString::number(row + m_dptr->m_start);  

  81. }  

  82.   

  83. QHash<int, QByteArray> DynamicListModel::roleNames() const  

  84. {  

  85.     return m_dptr->m_roleNames;  

  86. }  

  87.   

  88. void DynamicListModel::loadMore(bool forward)  

  89. {  

  90.     beginResetModel();  

  91.     if(forward)m_dptr->pageDown();  

  92.     else m_dptr->pageUp();  

  93.     endResetModel();  

  94. }  

  95.   

  96. int DynamicListModel::pageSize()  

  97. {  

  98.     return m_dptr->m_pageSize;  

  99. }  

  100.   

  101. void DynamicListModel::setPageSize(int size)  

  102. {  

  103.     m_dptr->m_pageSize = size;  

  104.     m_dptr->adjustPageRange();  

  105.     emit pageSizeChanged(size);  

  106. }  

  107.   

  108. int DynamicListModel::total()  

  109. {  

  110.    return m_dptr->m_total;  

  111. }  

  112.   

  113. void DynamicListModel::setTotal(int total)  

  114. {  

  115.     m_dptr->m_total = total;  

  116.     m_dptr->adjustPageRange();  

  117.     emit totalChanged(total);  

  118. }  


    DynamicListModel仅仅是演示用法,使用m_start、m_end、m_total、m_pageSize四个整型变量来模拟实际的数 据。而data()方法,将ListView内的行序号加上m_start转换为字符串返回,就是我们在ListView界面上看到了文字了。

    loadMore()函数,区分向前还是向后加载数据,它调用DynamicListModel的pageDown()、pageUp()来更新内部的数 据状态。在loadMore()一开始,调用beginResetModel(),通知关联到DynamicListModel上的view们刷新自己, 当内部数据状态更新结束后,调用endResetModel()来通知view们,这样view们就会刷新,最终在实例化item delegate时调用data()方法来准备数据,此时m_start已变化,所以界面上看到的数字也跟着变了。

导出C++ Model

    这个简单,我们在《Qt Quick 之 QML 与 C++ 混合编程详解》一文中已经讲过。直接看main.cpp:

[cpp] view plaincopy

  1. #include <QGuiApplication>  

  2. #include <QQmlApplicationEngine>  

  3. #include <QQmlContext>  

  4. #include "dynamicModel.h"  

  5.   

  6. int main(int argc, char *argv[])  

  7. {  

  8.     QGuiApplication app(argc, argv);  

  9.   

  10.     QQmlApplicationEngine engine;  

  11.     QQmlContext *ctx = engine.rootContext();  

  12.     ctx->setContextProperty("dynamicModel"new DynamicListModel());  

  13.     engine.load(QUrl(QStringLiteral("qrc:///main.qml")));  

  14.   

  15.     return app.exec();  

  16. }  


QML代码介绍

    是时候看看main.qml了:

[javascript] view plaincopy

  1. import QtQuick 2.2  

  2. import QtQuick.Window 2.1  

  3. import QtQuick.Controls 1.2  

  4. import QtQuick.Layouts 1.1  

  5. import QtQuick.Controls.Styles 1.2  

  6.   

  7. Window {  

  8.     width: 320;  

  9.     height: 480;  

  10.     minimumWidth: 300;  

  11.     minimumHeight: 480;  

  12.     visible: true;  

  13.     id: root;  

  14.   

  15.     Component {  

  16.         id: listDelegate;  

  17.         Text {  

  18.             id: wrapper;  

  19.             width: parent.width;  

  20.             height: 32;  

  21.             font.pointSize: 15;  

  22.             verticalAlignment: Text.AlignVCenter;  

  23.             horizontalAlignment: Text.AlignHCenter;  

  24.             text: content;  

  25.             color: ListView.view.currentIndex == index ? "red" : "blue";  

  26.             MouseArea {  

  27.                 anchors.fill: parent;  

  28.                 onClicked: {  

  29.                     if(wrapper.ListView.view.currentIndex != index){  

  30.                         wrapper.ListView.view.currentIndex = index;  

  31.                     }  

  32.                 }  

  33.             }  

  34.         }  

  35.     }  

  36.   

  37.     ListView {  

  38.         id: dynamicList;  

  39.         z: 1;  

  40.         anchors.fill: parent;  

  41.         anchors.margins: 10;  

  42.   

  43.         delegate: listDelegate;  

  44.         model: dynamicModel;  

  45.   

  46.         focus: true;  

  47.         activeFocusOnTab: true;  

  48.         highlight: Rectangle {  

  49.             color: "steelblue";  

  50.         }  

  51.   

  52.         property real contentYOnFlickStarted: 0;  

  53.         onFlickStarted: {  

  54.             //console.log("start,origY - ", originY, " contentY - ", contentY);  

  55.             contentYOnFlickStarted = contentY;  

  56.         }  

  57.   

  58.         onFlickEnded: {  

  59.             //console.log("end,origY - ", originY, " contentY - ", contentY);  

  60.             dynamicModel.loadMore(contentY < contentYOnFlickStarted);  

  61.         }  

  62.     }  

  63. }  


    定义ListView对象时,指定其model为main()函数中导出的dynamicModel,其它的代码不必细说了,咱们单看实现下拉(上拉)刷新的关键代码。

    onFlickStarted信号处理器,在这里我们仅仅是将flick开始时的contentY记录到contentYOnFlickStarted属性中。

    onFlickEnded信号处理器,这里比较flick结束时的contentY和开始时的contentY(即contentYOnFlickStarted),结束时小,说明是下拉,结束时大,说明是上拉。根据比较结果调用loadMore()。

    好啦,就这么简单了。看看效果。

下拉刷新效果

    图1是初始效果:


             图1动态刷新列表初始效果

    图2是下拉了两次后的效果:


             图2 下拉刷新后的效果

    图3是从图2所示状态上拉后的效果:


             图3 上拉后的效果


    版权所有foruok,转载请注明出处:http://blog.csdn.net/foruok

    好啦,解说完毕。

    回顾本系列文章:


本文转载自:http://blog.csdn.net/foruok/article/details/39052729

共有 人打赏支持
上一篇: blog
41245110
粉丝 0
博文 28
码字总数 2842
作品 0
南通
私信 提问
Qt Quick之ListView下拉刷新数据

Qt Quick里的ListView,本身是Flickable的派生类,当你用鼠标拖曳或者手指触摸(触摸屏)时,会产生flickStarted和flickEnded两个信号,利用这两个信号,就可以实现下拉刷新数据,当然上拉刷...

foruok
2014/09/04
0
0
Qt Quick里的图形效果(Graphical Effects)

Qt Quick 提供了 Graphical Effects ,我在《Qt Quick核心编程》一书中限于篇幅没有介绍,这里补上吧。 Graphical Effects ,姑且叫作图形效果吧。它提供了 Blend 、 Color 等好几类效果,有...

foruok
2015/01/14
0
0
Qt Quick里的图形效果——混合(Blend)

Blend 元素用指定的模式混合两个 Item 。在我们使用 QPainter 绘图时,支持 Composition Modes ,Blend 干的事儿与此类似。 使用 Blend 需要: snippetid="579325" snippetfilename="blog20...

foruok
2015/01/14
0
0
重写ListView实现下拉刷新上拉加载

安卓本身的ListView没有刷新功能,要想实现这一功能,就得继承ListView并重写它的方法。同时也要实现其OnScrollListener这一接口。 下拉刷新,需要在原本的ListView上部添加一个Head,ListV...

ZytCandy
2014/08/07
0
4
滑动事件总结(刷新,加载更多,嵌套滑动)

下拉刷新 在Api21之前,ListView和GridView的使用相当普遍,包括下拉刷新我们也可以使用它,利用他的addHeaderView()和addFooterView()方法,或者使用父级中隐藏View的方式来实现; 在A...

卐字旗下的余晖
2016/06/07
101
0

没有更多内容

加载失败,请刷新页面

加载更多

PHP生成CSV之内部换行

当我们使用PHP将采集到的文件内容保存到csv文件时,往往需要将采集内容进行二次过滤处理才能得到需要的内容。比如网页中的换行符,空格符等等。 对于空格等处理起来都比较简单,这里我们单独...

豆花饭烧土豆
今天
1
0
使用 mjml 生成 thymeleaf 邮件框架模板

发邮件算是系统开发的一个基本需求了,不过搞邮件模板实在是件恶心事,估计搞过的同仁都有体会。 得支持多种客户端 支持响应式 疼彻心扉的 outlook 多数客户端只支持 inline 形式的 css 布局...

郁也风
今天
4
0
让哲学照亮我们的人生——读《医务工作者需要学点哲学》有感2600字

让哲学照亮我们的人生——读《医务工作者需要学点哲学》有感2600字: 作者:孙冬梅;以前读韩国前总统朴槿惠的著作《绝望锻炼了我》时,里面有一句话令我印象深刻,她说“在我最困难的时期,...

原创小博客
今天
4
0
JAVA-四元数类

public class Quaternion { private final double x0, x1, x2, x3; // 四元数构造函数 public Quaternion(double x0, double x1, double x2, double x3) { this.x0 = ......

Pulsar-V
今天
17
0
Xshell利用Xftp传输文件,使用pure-ftpd搭建ftp服务

Xftp传输文件 如果已经通过Xshell登录到服务器,此时可以使用快捷键ctrl+alt+f 打开Xftp并展示Xshell当前的目录,之后直接拖拽传输文件即可。 pure-ftpd搭建ftp服务 pure-ftpd要比vsftp简单,...

野雪球
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部