zoukankan      html  css  js  c++  java
  • Qt实现小功能之列表无限加载(创意很不错:监听滚动条事件,到底部的时候再new QListWidgetItem)

    概念介绍

          无限加载与瀑布流的结合在Web前端开发中的效果非常新颖,对于网页内容具备较好的表现形式。无限加载并没有一次性将内容全部加载进来,而是通过监听滚动条事件来刷新内容的。当用户往下拖动滚动条或使用鼠标滚轮的时候,页面会自动加载剩余的内容。如下:

          简约而不简单,正是这种别出心裁,突破常规的设计才能得到用户的青睐……

    实现思路

           在前端开发可以使用一些jQuery插件实现这种效果,后台只需要准备好数据就行了。在Qt中如何给列表组件(QListWidget,QTreeWidget, QTableWidget)或试图(QListView, QTreeView, QTableView)添加这样的效果呢?上面的无限加载的核心原理其实就是使用javascript侦听浏览器的滚动条事件。那么在Qt里面这样做就简单了。我们知道Qt中有一个基类叫做QAbstractScrollArea,它是一个代表可滚动区域的抽象基类。因此,这个类中有许多和滚动条操作相关的方法。QAbstractScrollArea恰好又是Q*View的父类,这正好为我们提供了操作滚动条的机会。

           新建一个基于窗体的Qt应用程序工程,并从QListWIdget派生出一个子类:MListWidget。为什么呢?因为我们打算对鼠标滚轮事件作出一点点不一样的动作:当滚动条滚动的时候在主窗口的lineEdit中更新滚动条的当前位置;当滚动条滚到最底端的时候发送一个信号,以此更新ListWidget中的数据内容。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    // mlistwidget.h
    class MListWidget : public QListWidget
    {
        Q_OBJECT
    public:
        MListWidget(QWidget *parent);
        ~MListWidget();
     
    signals:
        void msliderChanged(int p);
        void reachedBottom();
     
    private slots:
        void onSliderChanged(int p);
         
    private:
        QScrollBar* m_vscrollBar;
    };
     
    // mlistwidget.cpp
    MListWidget::MListWidget(QWidget *parent)
        : QListWidget(parent)
    {
        m_vscrollBar = verticalScrollBar(); // 保持垂直滚动条
        connect(m_vscrollBar, SIGNAL(valueChanged(int)), this, SLOT(onSliderChanged(int)));
    }
     
    void MListWidget::onSliderChanged(int p)
    {
        int startRow = count();
        if (p == m_vscrollBar->maximum())
        {
            //QMessageBox::information(this, "Warning", "You reached the bottom of the vertical scroll bar!");
            emit reachedBottom(); // 1
        }
        emit msliderChanged(p);  // 2
    }

      注释1处发送了一个信号reachedBottom(),通知主窗体给ListWidget添加新的内容;注释2处的信号通知主窗体更新滚动条的当前位置值。

          接下来是主窗体的实现:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    // testscrollbar.h
    class TestScrollBar : public QMainWindow
    {
        Q_OBJECT
     
    public:
        TestScrollBar(QWidget *parent = 0);
        ~TestScrollBar();
     
    private slots:
        void onScrollBarMoved(int);
        void onReachedBottom();
     
    private:
        Ui::TestScrollBarClass ui;
    };
     
    // testscrollbar.cpp
    TestScrollBar::TestScrollBar(QWidget *parent)
        : QMainWindow(parent)
    {
        ui.setupUi(this);
     
        QListWidgetItem* temp;
     
        for (int i = 0; i < 100; i++)
        {
            temp = new QListWidgetItem();
            temp->setText("zhangzhongke_"+QString::number(i));
            ui.listWidget->insertItem(i, temp);
        }
     
        connect(ui.listWidget, SIGNAL(msliderChanged(int)), this, SLOT(onScrollBarMoved(int)));
        connect(ui.listWidget, SIGNAL(reachedBottom()), this, SLOT(onReachedBottom()));
    }
     
    void TestScrollBar::onScrollBarMoved(int v)
    {
        ui.lineEdit->setText(QString::number(v));
    }
    //  更新ListWidget中的内容,插入新数据到最后
    void TestScrollBar::onReachedBottom()
    {
        QListWidgetItem* temp;
        int startRow = ui.listWidget->count();
        for (int i = startRow; i < startRow+5; i++)
        {
            temp = new QListWidgetItem();
            temp->setText("hello_"+QString::number(i));
            ui.listWidget->insertItem(i, temp);
        }
     
    }

      这里从QListWidget中派生出了一个新的子类,记得在UI designer中对QListWidget组件进行提升(promote)。在Promote to...的时候填写我们派生出来的子类MListWidget。

    实际效果

          鼠标滚动到底部的时候,每次插入5条数据。

    参考

    • 瀑布流与无限加载的结合案例:http://down.admin5.com/demo/code_pop/18/745/

    http://www.cnblogs.com/csuftzzk/p/qt_infinitescroll.html

  • 相关阅读:
    JS垃圾回收机制
    Flex布局
    HTTP请求
    css基本布局方式
    阮一峰《ECMAScript 6 入门》读书笔记——模版标签
    阮一峰《ECMAScript 6 入门》读书笔记——变量解构赋值
    阮一峰《ECMAScript 6 入门》读书笔记——let与const
    闭包(Closure)
    CSS浮动布局带来的高度塌陷以及其解决办法
    CSS网页的布局
  • 原文地址:https://www.cnblogs.com/findumars/p/6025116.html
Copyright © 2011-2022 走看看