1. 程式人生 > >Qt:使用Model-View,動態的載入顯示資料

Qt:使用Model-View,動態的載入顯示資料

共有 main.cpp, Widget.h, Widget.cpp, Widget.ui, MyModel.h, MyModel.cpp 六個檔案。

關鍵在於Model中的資料是動態載入的,而不是一次性全載入到Model中。

/***************************************************

 *              main.cpp

 ***************************************************/

#include <QtGui/QApplication>

#include "Widget.h"

int main(int argc, char *argv[]) {

    QApplication a(argc, argv);

    Widget w;

    w.show();

    return a.exec();

}

/***************************************************

 *              Widget.h

 ***************************************************/

#ifndef WIDGET_H

#define WIDGET_H

#include <QWidget>

namespace Ui {

    class Widget;

}

class Widget : public QWidget {

    Q_OBJECT

public:

    explicit Widget(QWidget *parent = 0);

    ~Widget();

private:

    Ui::Widget *ui;

};

#endif // WIDGET_H

/***************************************************

 *              Widget.cpp

 ***************************************************/

#include "Widget.h"

#include "ui_Widget.h"

#include "MyModel.h"

Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) {

    ui->setupUi(this);

    MyModel *model = new MyModel(100020this);

    ui->tableView->setModel(model);

    ui->tableView->horizontalHeader()->setStretchLastSection(true);

}

Widget::~Widget() {

    delete ui;

}

/***************************************************

 *              MyModel.h

 ***************************************************/

#ifndef MYMODEL_H

#define MYMODEL_H

#include <QAbstractTableModel>

#include <QHash>

#include <QList>

class MyModel : public QAbstractTableModel {

public:

    explicit MyModel(int rowCount = 1000int pageSize = 10, QObject *parent = 0);

    virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;

    virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;

    virtual QVariant data( const QModelIndex &index, int role = Qt::DisplayRole) const;

private:

    QHash<intint> m_pageHash; // key頁碼值, value是此頁的第一項資料在dataList中的下標值

    QList<int> m_dataList; // 儲資料的容器

    int m_pageSize; // 頁顯示的資料量

    int m_rowCount; // 顯示的行數

// 這個下標是有規律可尋的但是是無序的.

// 同一頁碼中的數值的下標是有序的不同頁碼的資料之間是無序的.

    int indexOfRow(int row) const;

// 讀取資料可是以模擬生成的實際工程中很可能是從資料庫中動態讀取

    void fetchData(int page);

};

#endif // MYMODEL_H

/***************************************************

 *              MyModel.cpp

 ***************************************************/

#include "MyModel.h"

#include <QDebug>

MyModel::MyModel(int rowCount, int pageSize, QObject *parent) : QAbstractTableModel(parent) {

    this->m_pageSize = pageSize;

    this->m_rowCount = rowCount;

}

intMyModel::columnCount(const QModelIndex &parent) const {

    Q_UNUSED(parent);

return1// 以一列為示例如果是多列data list儲存的應該是物件

}

int MyModel::rowCount (const QModelIndex &parent) const {

    Q_UNUSED(parent);

    return m_rowCount;

}

QVariant MyModel::data( const QModelIndex &index, int role) const {

    if (!index.isValid()) { return QVariant(); }

    if (Qt::DisplayRole == role) {

        int i = indexOfRow(index.row());

        return m_dataList.at(i);

    }

    return QVariant();

}

int MyModel::indexOfRow(int row) const {

    int page = row / m_pageSize; // 頁顯示pageSize記錄

    if (!m_pageHash.contains(page)) {

// 如果此面的資料不存在則讀取資料到 data list

        (const_cast<MyModel *>(this))->fetchData(page);

    }

    return m_pageHash.value(page) + row % m_pageSize;

}

// 每次加載資料時,如果是耗時任務可以使用進度條顯示載入進度

// 也可以取消加但是這個時候data()函式中返回一個非有效的index

void MyModel::fetchData(int page) {

    int pageStartIndex = m_dataList.count(); // 儲此頁碼與其所對應的開始下標值

    m_pageHash.insert(page, pageStartIndex);

// 例如在這裡使用分頁查詢從資料庫裡讀取資料

    for (int i = 0; i < m_pageSize; ++i) {

        int data = page * m_pageSize + i;

        m_dataList.append(data);

// 快速拖動滾動條可以看到中間很多沒必要的資料沒有產生.

        qDebug() << data;

    }

}