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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM