文档章节

Qt Quick之ListView下拉刷新数据

41245110
 41245110
发布于 2015/06/05 21:41
字数 1237
阅读 134
收藏 1
点赞 0
评论 0

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

    好啦,解说完毕。

    回顾本系列文章:


© 著作权归作者所有

共有 人打赏支持
41245110
粉丝 0
博文 16
码字总数 2842
作品 0
南通
Qt Quick之ListView下拉刷新数据

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

foruok ⋅ 2014/09/04 ⋅ 0

Qt Quick里的图形效果(Graphical Effects)

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

foruok ⋅ 2015/01/14 ⋅ 0

Qt Quick里的图形效果——混合(Blend)

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

foruok ⋅ 2015/01/14 ⋅ 0

重写ListView实现下拉刷新上拉加载

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

ZytCandy ⋅ 2014/08/07 ⋅ 4

Android学习系列(15)--App列表之下拉刷新

Android的ListView是应用最广的一个组件,功能强大,扩展性灵活(不局限于ListView本身一个类),前面的文章有介绍分组,拖拽,3D立体,游标,圆角,而今天我们要介绍的是另外一个扩展ListVie...

chengche ⋅ 2014/01/08 ⋅ 0

【Android】RecyclerView下拉刷新与加载更多

知道自己不能做什么远比知道自己能做什么重要。 RecyclerView是Android L版本中新添加的控件,它的灵活性、可替代性、回收机制等比listview更好。可能对于一些使用过RecyclerView的开发者会说...

zrunker ⋅ 2017/10/26 ⋅ 0

滑动事件总结(刷新,加载更多,嵌套滑动)

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

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

Android自定义控件之ListView的下拉刷新与上拉加载

开发项目过程中基本都会用到listView的下拉刷新和上滑加载更多,为了方便重写的ListView来实现下拉刷新,同时添加了上拉自动加载更多的功能。 Android下拉刷新可以分为两种情况: 1.获取更多...

切切歆语 ⋅ 2016/11/07 ⋅ 0

如何刷新listView中的数据呢?

网上找了个ScrollView上拉和下拉刷新的demo,我的listView写在MainActivity中,如下: 然后ScrollView下拉和上拉刷新在自定义的MyListener中, 如果是在mainActivity中我就知道怎么更新,但是...

风中海岸 ⋅ 2016/04/20 ⋅ 3

Android 下拉刷新框架实现

前段时间项目中用到了下拉刷新功能,之前在网上也找到过类似的demo,但这些demo的质量参差不齐,用户体验也不好,接口设计也不行。最张没办法,终于忍不了了,自己就写了一个下拉刷新的框架,...

军歌 ⋅ 2014/06/23 ⋅ 1

没有更多内容

加载失败,请刷新页面

加载更多

下一页

两道面试题,带你解析Java类加载机制

在许多Java面试中,我们经常会看到关于Java类加载机制的考察,例如下面这道题: class Grandpa{ static { System.out.println("爷爷在静态代码块"); }} cl...

1527 ⋅ 20分钟前 ⋅ 0

SpringCloud(Data Flow)

dataflow-server

赵-猛 ⋅ 30分钟前 ⋅ 0

深入理解Java虚拟机

这本书我读到第8章,之后就是在读不下去了。 读到后面是一种痛苦的体验,太多的东西是不全面的,大量的专有名词是没有解释的,读到最后很多东西仅仅是一个侧面,所以我觉得,这本书不适合初学...

颖伙虫 ⋅ 35分钟前 ⋅ 0

B树和B+树的总结

B树 为什么要B树 磁盘中有两个机械运动的部分,分别是盘片旋转和磁臂移动。盘片旋转就是我们市面上所提到的多少转每分钟,而磁盘移动则是在盘片旋转到指定位置以后,移动磁臂后开始进行数据的...

浮躁的码农 ⋅ 38分钟前 ⋅ 0

NanoPi NEO core/ Ubuntu16.04单网卡配置3个IP地址(2个静态,1个动态)

配置 root@NanoPi-NEO-Core:/etc/network# cat interfacesauto loiface lo inet loopbackallow-hotplug eth0iface eth0 inet static address 172.31.188.249 netmask 255.......

SamXIAO ⋅ 今天 ⋅ 0

三步为你的App集成LivePhoto功能

摘要:LivePhoto是iOS9新推出的一种拍照方式,类似于拍摄Gif图或录制视频片段生成图片。如果没有画面感,可以联想《哈利波特》霍格沃茨城堡的壁画,哈哈,很炫酷有木有,但坑爹的是只有iphone6S以...

壹峰 ⋅ 今天 ⋅ 0

centos7 git安装

由于centos中的源仓库中git不是最新版本,需要进行源码安装。 1、查看yum仓库git信息 [root@iZm5e3d4r5i5ml889vh6esZ zh]# yum info gitLoaded plugins: fastestmirrorLoading mirror s...

xixingzhe ⋅ 今天 ⋅ 0

input file 重复上传同一张图片失效的解决办法

解决办法 方法一:来回切换input[type='file']的type属性值,可以是‘text’,'button','button'....,然后再切换回来‘file’ 方法二:每次取消图片预览后,重置input[type='file']的value的...

时刻在奔跑 ⋅ 今天 ⋅ 0

Mahout推荐算法API详解

前言 用Mahout来构建推荐系统,是一件既简单又困难的事情。简单是因为Mahout完整地封装了“协同过滤”算法,并实现了并行化,提供非常简单的API接口;困难是因为我们不了解算法细节,很难去根...

xiaomin0322 ⋅ 今天 ⋅ 0

WampServer默认web服务器根目录位置

安装WampServer之后的web服务器根目录默认位置在WampServer安装目录下的www:

临江仙卜算子 ⋅ 今天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部