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

xiaoxiao2021-02-28  85

原文地址

概念介绍

      无限加载与瀑布流的结合在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条数据。

Qt-vs-addin的小问题

       使用Visual Studio进行Qt开发的时候,需要安装一个插件。然而有时候这个插件的一些工具却莫名其妙的失效:

       其中qt5appwrapper.exe用于编辑Qt工程中的UI文件,也就是Qt Designer;qt5rceditor.exe则用于编辑Qt资源文件。此时在VS中却无法正常打开,并报如上错误。具体的原因不知道是什么,修复的方法如下:

       对工程中的*.ui文件或*.qrc文件右键,选择“打开方式...”,弹出如下对话框,并点击“添加...”按钮,选择qt-vs-addin的安装目录,找到上述的两个可执行文件:

        至此,添加完毕。记得将新添加的这个程序设置为默认值,也就是默认的打开工具。

参考

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

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

转载请注明原文地址: https://www.6miu.com/read-35993.html

最新回复(0)