五十一、Qt之通用數據庫分頁

DBAPI.h

#ifndef DBAPI_H
#define DBAPI_H

#include <QObject>
#include <QMutex>

class QtSql;
class QTableView;
class QLabel;
class QAbstractButton;
class QComboBox;
class QSqlQueryModel;

class DBAPI : public QObject
{
    Q_OBJECT
private:
    explicit DBAPI(QObject *parent = 0);
    static DBAPI *_instance;

    void BindData(QString sql);

    int startIndex;             //分頁開始索引,每次翻頁都變動
    QString tempSql;            //臨時SQL語句
    QString sql;
    QSqlQueryModel *queryModel; //查詢模型

    QLabel *labPageCount;       //總頁數
    QLabel *labPageCurrent;     //當前頁
    QLabel *labResultCount;     //總記錄數
    QLabel *labResultCurrent;   //每頁記錄數
    QLabel *labInfo;            //總頁數當前頁總記錄數每頁記錄數

    QTableView *tableView;      //顯示數據的表格對象
    QAbstractButton *btnFirst;  //第一頁按鈕對象
    QAbstractButton *btnPre;    //上一頁按鈕對象
    QAbstractButton *btnNext;   //下一頁按鈕對象
    QAbstractButton *btnLast;   //末一頁按鈕對象

    int resultCurrent;          //每頁顯示記錄數
    int resultCount;            //總記錄數
    int pageCount;              //總頁數
    int pageCurrent;            //當前第幾頁

public:
    static DBAPI *Instance() {
        static QMutex mutex;
        if (!_instance) {
            QMutexLocker locker(&mutex);
            if (!_instance) {
                _instance = new DBAPI;
            }
        }
        return _instance;
    }

    //設置需要顯示數據的表格,數據翻頁對應的按鈕
    void SetControl(QTableView *tableView, QLabel *labInfo,
                    QAbstractButton *btnFirst, QAbstractButton *btnPre,
                    QAbstractButton *btnNext, QAbstractButton *btnLast);

    void SetControl(QTableView *tableView, QLabel *labPageCount, QLabel *labPageCurrent,
                    QLabel *labResultCount, QLabel *labResultCurrent,
                    QAbstractButton *btnFirst, QAbstractButton *btnPre,
                    QAbstractButton *btnNext, QAbstractButton *btnLast);

    //綁定查詢數據,帶分頁/行數/條件/排序/列名/列寬
    void BindDataSelect(QString tableName, QString orderSql, QString where, int resultCurrent,
                        QList<QString> columnNames, QList<int> columnWidths);

    //綁定數據到下拉框
    void BindData(QString columnName, QString orderColumn, QString tableName, QComboBox *cbox);
    void BindData(QString columnName, QString orderColumn, QString tableName, QList<QComboBox *> cboxs);

signals:

private slots:
    void first();       //第一頁
    void previous();    //上一頁
    void next();        //下一頁
    void last();        //末一頁

};

#endif // DBAPI_H

DBAPI.cpp

#if _MSC_VER >= 1600
#pragma execution_character_set("utf-8")
#endif

#include "dbapi.h"
#include "myhelper.h"

/* 說明:數據庫查詢及翻頁模塊
 * 功能:數據庫查詢及翻頁處理
 * 作者:劉典武  QQ:517216493
 * 時間:2014-8-27  檢查:2014-9-10
 */
DBAPI *DBAPI::_instance = 0;
DBAPI::DBAPI(QObject *parent) :
    QObject(parent)
{
    startIndex = 0;
    tempSql = "";
    sql = "";
    resultCurrent = 0;
    resultCount = 0;
    pageCount = 0;
    pageCurrent = 1;

    this->tableView = 0;
    this->labInfo = 0;
    this->labPageCount = 0;
    this->labPageCurrent = 0;
    this->labResultCount = 0;
    this->labResultCurrent = 0;

    this->btnFirst = 0;
    this->btnPre = 0;
    this->btnNext = 0;
    this->btnLast = 0;
}

//設置顯示數據的表格控件,當前翻頁信息的標籤控件等
void DBAPI::SetControl(QTableView *tableView, QLabel *labInfo,
                       QAbstractButton *btnFirst, QAbstractButton *btnPre,
                       QAbstractButton *btnNext, QAbstractButton *btnLast)
{
    this->tableView = tableView;
    this->labInfo = labInfo;
    this->labPageCount = 0;
    this->labPageCurrent = 0;
    this->labResultCount = 0;
    this->labResultCurrent = 0;

    this->btnFirst = btnFirst;
    this->btnPre = btnPre;
    this->btnNext = btnNext;
    this->btnLast = btnLast;

    this->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
    queryModel = new QSqlQueryModel(tableView);

    //掛載翻頁按鈕事件
    connect(btnFirst, SIGNAL(clicked()), this, SLOT(first()));
    connect(btnPre, SIGNAL(clicked()), this, SLOT(previous()));
    connect(btnNext, SIGNAL(clicked()), this, SLOT(next()));
    connect(btnLast, SIGNAL(clicked()), this, SLOT(last()));
}

void DBAPI::SetControl(QTableView *tableView, QLabel *labPageCount, QLabel *labPageCurrent,
                       QLabel *labResultCount, QLabel *labResultCurrent,
                       QAbstractButton *btnFirst, QAbstractButton *btnPre,
                       QAbstractButton *btnNext, QAbstractButton *btnLast)
{
    this->tableView = tableView;
    this->labInfo = 0;
    this->labPageCount = labPageCount;
    this->labPageCurrent = labPageCurrent;
    this->labResultCount = labResultCount;
    this->labResultCurrent = labResultCurrent;

    this->btnFirst = btnFirst;
    this->btnPre = btnPre;
    this->btnNext = btnNext;
    this->btnLast = btnLast;

    this->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
    queryModel = new QSqlQueryModel(tableView);

    //掛載翻頁按鈕事件
    connect(btnFirst, SIGNAL(clicked()), this, SLOT(first()));
    connect(btnPre, SIGNAL(clicked()), this, SLOT(previous()));
    connect(btnNext, SIGNAL(clicked()), this, SLOT(next()));
    connect(btnLast, SIGNAL(clicked()), this, SLOT(last()));
}

//綁定數據到下拉框
void DBAPI::BindData(QString columnName, QString orderColumn, QString tableName, QComboBox *cbox)
{
    QSqlQuery query;
    query.exec("select " + columnName + " from " + tableName + " order by " + orderColumn + " asc");
    while (query.next()) {
        cbox->addItem(query.value(0).toString());
    }
}

void DBAPI::BindData(QString columnName, QString orderColumn, QString tableName, QList<QComboBox *> cboxs)
{
    QSqlQuery query;
    query.exec("select " + columnName + " from " + tableName + " order by " + orderColumn + " asc");
    while (query.next()) {
        foreach (QComboBox * cbox, cboxs) {
            cbox->addItem(query.value(0).toString());
        }
    }
}

void DBAPI::BindData(QString sql)
{
    queryModel->setQuery(sql);
    tableView->setModel(queryModel);

    if (labInfo != 0) {
        labInfo->setText(QString("共 %1 條  每頁 %2 條  共 %3 頁  第 %4 頁").arg(resultCount).arg(resultCurrent).arg(pageCount).arg(pageCurrent));
    } else {
        labPageCount->setText(QString("共 %1 頁").arg(pageCount));
        labPageCurrent->setText(QString("第 %1 頁").arg(pageCurrent));
        labResultCount->setText(QString("共 %1 條").arg(resultCount));
        labResultCurrent->setText(QString("每頁 %1 條").arg(resultCurrent));
    }
}

//分頁綁定查詢數據到表格,指定排序列
void DBAPI::BindDataSelect(QString tableName, QString orderSql, QString where, int resultCurrent,
                           QList<QString> columnNames, QList<int> columnWidths)
{
    startIndex = 0; //重置開始索引
    pageCurrent = 1;
    this->resultCurrent = resultCurrent;

    //開始分頁綁定數據前,計算好總數據量以及行數
    tempSql = "select count(*) from " + tableName + " " + where;
    QSqlQuery query;
    query.prepare(tempSql);
    query.exec();
    query.first();
    resultCount = query.value(0).toInt();

    int yushu = resultCount % resultCurrent;
    //不存在餘數,說明是整行,例如300%5==0
    if (yushu == 0) {
        if (resultCount > 0 && resultCount < resultCurrent) {
            pageCount = 1;
        } else {
            pageCount = resultCount / resultCurrent;
        }
    } else {
        pageCount = (resultCount / resultCurrent) + 1;
    }

    //2014-10-9增加翻頁按鈕可用不可用處理,如果只有一頁數據,則翻頁按鈕不可用
    if (pageCount <= 1) {
        btnFirst->setEnabled(false);
        btnLast->setEnabled(false);
        btnNext->setEnabled(false);
        btnPre->setEnabled(false);
    } else {
        btnFirst->setEnabled(true);
        btnLast->setEnabled(true);
        btnNext->setEnabled(true);
        btnPre->setEnabled(true);
    }

    tempSql = "select * from " + tableName + " " + where + " order by " + orderSql;
    sql = QString("%1 limit %2,%3;").arg(tempSql).arg(startIndex).arg(resultCurrent); //組織分頁SQL語句
    BindData(sql);

    //依次設置列標題列寬
    int count = tableView->model()->columnCount();
    for (int i = 0; i < count ; i++) {
        queryModel->setHeaderData(i, Qt::Horizontal, columnNames.at(i)); //設置列標題
        tableView->setColumnWidth(i, columnWidths.at(i)); //設置列寬
    }
}

//第一頁
void DBAPI::first()
{
    if (pageCount > 1) {
        startIndex = 0;
        pageCurrent = 1;
        sql = QString("%1 limit %2,%3;").arg(tempSql).arg(startIndex).arg(resultCurrent);
        BindData(sql);
        btnLast->setEnabled(true);
        btnNext->setEnabled(true);
    }

    btnFirst->setEnabled(false);
    btnPre->setEnabled(false);
}

//上一頁
void DBAPI::previous()
{
    if (pageCurrent > 1) {
        pageCurrent--;
        startIndex -= resultCurrent;
        sql = QString("%1 limit %2,%3;").arg(tempSql).arg(startIndex).arg(resultCurrent);
        BindData(sql);
        btnLast->setEnabled(true);
        btnNext->setEnabled(true);
    }

    if (pageCurrent == 1) {
        btnFirst->setEnabled(false);
        btnPre->setEnabled(false);
    }
}

//下一頁
void DBAPI::next()
{
    if (pageCurrent < pageCount) {
        pageCurrent++;
        startIndex += resultCurrent;
        sql = QString("%1 limit %2,%3;").arg(tempSql).arg(startIndex).arg(resultCurrent);
        BindData(sql);
        btnFirst->setEnabled(true);
        btnPre->setEnabled(true);
    }

    if (pageCurrent == pageCount) {
        btnLast->setEnabled(false);
        btnNext->setEnabled(false);
    }
}

//末一頁
void DBAPI::last()
{
    if (pageCount > 0) {
        startIndex = (pageCount - 1) * resultCurrent;
        pageCurrent = pageCount;
        sql = QString("%1 limit %2,%3;").arg(tempSql).arg(startIndex).arg(resultCurrent);
        BindData(sql);
        btnFirst->setEnabled(true);
        btnPre->setEnabled(true);
    }

    btnLast->setEnabled(false);
    btnNext->setEnabled(false);
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章