Qt数据库分页

参考6.5大佬的数据库分页, 但6.5大佬的数据库分页是有上一页和下一页,无法直接跳到指定的页面。直接代码:

rsqltablemodel.h
#ifndef RSQLTABLEMODEL_H
#define RSQLTABLEMODEL_H
#pragma execution_character_set("utf-8")
#include <QSqlTableModel>

class RSqlTableModel : public QSqlQueryModel
{
    Q_OBJECT
public:
    explicit RSqlTableModel(QObject *parent = nullptr);
    void setTimeColumn(int timeColumn,int startTimeColumn = -1){this->timeColumn = timeColumn;this->startTimeColumn = startTimeColumn;}
    void setStatusColumn(int statusColumn = -1){this->statusColumn = statusColumn;}
protected:
    QVariant data(const QModelIndex &index, int role) const override;
signals:
private:
    int timeColumn = -1;
    int startTimeColumn = -1;
    int statusColumn = -1;
};

#endif // RSQLTABLEMODEL_H
rsqltablemodel.cpp
#include "rsqltablemodel.h"
#include <QDebug>
#include <QDateTime>

RSqlTableModel::RSqlTableModel(QObject *parent) : QSqlQueryModel(parent)
{

}


QVariant RSqlTableModel::data(const QModelIndex &index, int role) const
{
    QVariant ret = QSqlQueryModel::data(index,role) ;

    if (Qt::TextAlignmentRole == role) {
        ret = Qt::AlignCenter;
    }
    if(role == Qt::DisplayRole){
        if(startTimeColumn >= 0 && index.column() == startTimeColumn ){
            QDateTime dt = QDateTime::fromSecsSinceEpoch(ret.toLongLong());
            return dt.toString("yyyy-MM-dd hh:mm:ss");
        }
        else if(timeColumn >= 0 && index.column() == timeColumn){
            QDateTime dt = QDateTime::fromSecsSinceEpoch(ret.toLongLong());
            return dt.toString("yyyy-MM-dd hh:mm:ss");
        }else if(statusColumn >= 0 && index.column() == statusColumn){
            if(ret.toInt() == 0){
                return QVariant("断");
            }else if(ret.toInt() == 1){
                return QVariant("开");
            }else{
                return ret;
            }
        }else{
            return ret;
        }
    }else{
        return ret;
    }

}

dbpage.h
#ifndef DBPAGE_H
#define DBPAGE_H


#include <QtGui>
#include <QtSql>
#if (QT_VERSION > QT_VERSION_CHECK(5,0,0))
#include <QtWidgets>
#endif

#include "rsqltablemodel.h"


//计算复合条件的记录总行数,以便分页
class DbCountThread : public QThread
{
    Q_OBJECT
public:
    explicit DbCountThread(QObject *parent = 0);
    void setSqlDatabase(const QSqlDatabase &db){this->db = db;}
private:
    QSqlDatabase db;
    QString connName;   //数据库连接名称
    QString sql;        //要执行的查询语句

protected:
    void run();

signals:
    void receiveCount(quint32 count, double msec);

public slots:
    //设置数据库连接名称
    void setConnName(const QString &connName);

    //设置要执行的查询语句
    void setSql(const QString &sql);

};

class DbPage : public QObject
{
    Q_OBJECT
public:
    enum DbType {
        DbType_Sqlite = 0,      //sqlite数据库
        DbType_MySql = 1,       //mysql数据库
        DbType_SqlServer = 3,   //sqlserver数据库
        DbType_Access = 4,      //access数据库
        DbType_PostgreSQL = 5   //postgresql数据库
    };

    static DbPage *Instance();
    explicit DbPage(QObject *parent = 0);

    RSqlTableModel *getQueryModel(){return queryModel;}

    //绑定数据到下拉框
    static void bindData(const QString &columnName, const QString &orderColumn, const QString &tableName,
                         QComboBox *cbox, const QString &connName = "qt_sql_default_connection");
    static void bindData(const QString &columnName, const QString &orderColumn, const QString &tableName,
                         QList<QComboBox *> cboxs, const QString &connName = "qt_sql_default_connection");

private:
    static QScopedPointer<DbPage> self;

    int startIndex;             //分页开始索引,每次翻页都变动
    QString tempSql;            //临时SQL语句
    QString sql;                //sql语句
    RSqlTableModel *queryModel;  //查询模型
    QSqlDatabase db;

    QTableView *tableView;      //显示数据的表格对象

    QString countName;          //统计表行数用字段
    QString connName;           //所使用的数据库连接名
    DbType dbType;              //数据库类型

    quint32 pageCurrent;        //当前第几页
    quint32 pageCount;          //总页数
    quint32 resultCount;        //总记录数
    quint32 resultCurrent;      //每页显示记录数

    QString tableName;          //表名
    QString selectColumn;       //要查询的字段集合
    QString orderSql;           //排序语句
    QString whereSql;           //条件语句
    QList<QString> columnNames; //列名集合
    QList<int> columnWidths;    //列宽集合

    int insertColumnIndex;      //插入的列的索引位置
    QString insertColumnName;   //插入的列的标题
    int insertColumnWidth;      //插入的列的宽度
    QString likeSql;            //模糊查询

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

private slots:
    //绑定sql语句到表格
    void bindData(const QString &sql);

    //收到记录行数
    void slot_receiveCount(quint32 count, double msec);

signals:
    void receivePage(quint32 pageCurrent, quint32 pageCount, quint32 resultCount, quint32 resultCurrent);
    void receiveCount(quint32 count, double msec);
    void signalPageCount(int pageCount);

public slots:
    void setSqlDatabase(const QSqlDatabase &db){this->db = db;}
    //设置需要显示数据的表格,数据翻页对应的按钮
    void setControl(QTableView *tableView, const QString &connName = "qt_sql_default_connection");

    //设置数据库连接名称
    void setConnName(const QString &connName);

    //设置数据库类型
    void setDbType(const DbType &dbType);

    //设置要查询的表名
    void setTableName(const QString &tableName);

    //设置要查询的字段列名集合
    void setSelectColumn(const QString &selectColumn);

    //设置排序sql
    void setOrderSql(const QString &orderSql);

    //设置条件sql
    void setWhereSql(const QString &whereSql);

    //设置每页显示多少行数据
    void setResultCurrent(int resultCurrent);

    //设置列名称集合
    void setColumnNames(const QList<QString> &columnNames);

    //设置列宽度集合
    void setColumnWidths(const QList<int> &columnWidths);

    //设置所有列居中
    void setAllCenter(bool allCenter);

    //设置居中对齐列索引集合
    void setAlignCenterColumn(const QList<int> &alignCenterColumn);

    //设置右对齐列索引集合
    void setAlignRightColumn(const QList<int> &alignRightColumn);

    //设置插入的列的索引
    void setInsertColumnIndex(int insertColumnIndex);

    //设置插入的列的标题
    void setInsertColumnName(const QString &insertColumnName);

    //设置插入的列的宽度
    void setInsertColumnWidth(int insertColumnWidth);

    //执行查询
    void select();

    void slotCurrentPageChanged(int page);

    void setTimeColumn(int timeColumn,int startTimeColumn = -1);
    void setStatusColumn(int statusColumn = -1);
};

#endif // DBPAGE_H
dbpage.cpp
#include "dbpage.h"

DbCountThread::DbCountThread(QObject *parent) : QThread(parent)
{
    connName = "qt_sql_default_connection";
    sql = "select 1";

    connect(this, SIGNAL(finished()), this, SLOT(deleteLater()));
}

void DbCountThread::run()
{
    //计算用时
    QDateTime dtStart = QDateTime::currentDateTime();
    QSqlQuery query(db);
    if(query.exec(sql)){
        query.next();

        int count = query.value(0).toUInt();

        QDateTime dtEnd = QDateTime::currentDateTime();
        double msec = dtStart.msecsTo(dtEnd);
        emit receiveCount(count, msec);
    }else{
        qDebug()<<__FUNCTION__<<query.lastError().text();
    }



}

void DbCountThread::setConnName(const QString &connName)
{
    this->connName = connName;
}

void DbCountThread::setSql(const QString &sql)
{
    this->sql = sql;
}


QScopedPointer<DbPage> DbPage::self;
DbPage *DbPage::Instance()
{
    if (self.isNull()) {
        QMutex mutex;
        QMutexLocker locker(&mutex);
        if (self.isNull()) {
            self.reset(new DbPage);
        }
    }

    return self.data();
}

DbPage::DbPage(QObject *parent) : QObject(parent)
{
    startIndex = 0;
    tempSql = "";
    sql = "";
    queryModel = new RSqlTableModel(this);

    pageCurrent = 1;
    pageCount = 0;
    resultCount = 0;
    resultCurrent = 0;


    tableView = 0;

    countName = "*";
    connName = "qt_sql_default_connection";
    dbType = DbType_MySql;

    pageCurrent = 0;
    pageCount = 0;
    resultCount = 0;
    resultCurrent = 30;

    tableName = "";
    selectColumn = "*";
    orderSql = "";
    whereSql = "";
    columnNames.clear();
    columnWidths.clear();

    insertColumnIndex = -1;
    insertColumnName = "";
    insertColumnWidth = 50;
}

void DbPage::bindData(const QString &columnName, const QString &orderColumn, const QString &tableName,
                      QComboBox *cbox, const QString &connName)
{
    QSqlQuery query(QSqlDatabase::database(connName));
    query.exec("select " + columnName + " from " + tableName + " order by " + orderColumn + " asc");
    while (query.next()) {
        cbox->addItem(query.value(0).toString());
    }
}

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

void DbPage::bindData(const QString &sql)
{
    queryModel->setQuery(sql, db);
    tableView->setModel(queryModel);
    tableView->verticalHeader()->setVisible(false);

    //依次设置列标题列宽
    int columnCount = tableView->model()->columnCount();
    int nameCount = columnNames.count();
    columnCount = columnCount > nameCount ? nameCount : columnCount;

    QList<QString> columnNames = this->columnNames;
    QList<int> columnWidths = this->columnWidths;

    //根据设置添加新列,将对应新列的标题名称和宽度按照索引位置插
    if (insertColumnIndex >= 0) {
        columnCount++;
        columnNames.insert(insertColumnIndex, insertColumnName);
        columnWidths.insert(insertColumnIndex, insertColumnWidth);
        queryModel->insertColumn(insertColumnIndex);
    }

    //设置列标题和列宽度
    for (int i = 0; i < columnCount; i++) {
        queryModel->setHeaderData(i, Qt::Horizontal, columnNames.at(i));       
        //tableView->setColumnWidth(i, columnWidths.at(i));
    }

    //发送结果信号
    emit receivePage(pageCurrent, pageCount, resultCount, resultCurrent);
    emit  signalPageCount( pageCount);
}

void DbPage::slot_receiveCount(quint32 count, double msec)
{
    resultCount = count;

    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;
    }


    if(likeSql.isEmpty()){
        tempSql = QString("select %1 from %2 %3 order by %4").arg(selectColumn).arg(tableName).arg(whereSql).arg(orderSql);
        sql = QString("%1 limit %2,%3;").arg(tempSql).arg(startIndex).arg(resultCurrent); //组织分页SQL语句
    }else{
        sql = likeSql;
    }


    bindData(sql);
}

void DbPage::first()
{
    if (pageCount > 1) {
        startIndex = 0;
        pageCurrent = 1;
        sql = QString("%1 limit %2,%3;").arg(tempSql).arg(startIndex).arg(resultCurrent);
        bindData(sql);
    }

}

void DbPage::previous()
{
    if (pageCurrent > 1) {
        pageCurrent--;
        startIndex -= resultCurrent;
        sql = QString("%1 limit %2,%3;").arg(tempSql).arg(startIndex).arg(resultCurrent);
        bindData(sql);
    }

}

void DbPage::next()
{
    if (pageCurrent < pageCount) {
        pageCurrent++;
        startIndex += resultCurrent;
        sql = QString("%1 limit %2,%3;").arg(tempSql).arg(startIndex).arg(resultCurrent);
        bindData(sql);
    }


}

void DbPage::slotCurrentPageChanged(int page)
{
    pageCurrent = page;
    startIndex = resultCurrent * pageCurrent - resultCurrent;
    sql = QString("%1 limit %2,%3;").arg(tempSql).arg(startIndex).arg(resultCurrent);
    bindData(sql);
}

void DbPage::last()
{
    if (pageCount > 0) {
        startIndex = (pageCount - 1) * resultCurrent;
        pageCurrent = pageCount;
        sql = QString("%1 limit %2,%3;").arg(tempSql).arg(startIndex).arg(resultCurrent);
        bindData(sql);
    }

}

//设置显示数据的表格控件,当前翻页信息的标签控件等
void DbPage::setControl(QTableView *tableView,const QString &connName)
{
    this->tableView = tableView;


    this->countName = countName;
    this->connName = connName;
    this->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);


}

void DbPage::setConnName(const QString &connName)
{
    this->connName = connName;
}

void DbPage::setDbType(const DbPage::DbType &dbType)
{
    this->dbType = dbType;
}

void DbPage::setTableName(const QString &tableName)
{
    this->tableName = tableName;
}

void DbPage::setSelectColumn(const QString &selectColumn)
{
    this->selectColumn = selectColumn;
}

void DbPage::setOrderSql(const QString &orderSql)
{
    this->orderSql = orderSql;
}

void DbPage::setWhereSql(const QString &whereSql)
{
    this->whereSql = whereSql;
}

void DbPage::setResultCurrent(int resultCurrent)
{
    this->resultCurrent = resultCurrent;
}

void DbPage::setColumnNames(const QList<QString> &columnNames)
{
    this->columnNames = columnNames;
}

void DbPage::setColumnWidths(const QList<int> &columnWidths)
{
    this->columnWidths = columnWidths;
}

void DbPage::setAllCenter(bool allCenter)
{
    //queryModel->setAllCenter(allCenter);
}

void DbPage::setAlignCenterColumn(const QList<int> &alignCenterColumn)
{
    //queryModel->setAlignCenterColumn(alignCenterColumn);
}

void DbPage::setAlignRightColumn(const QList<int> &alignRightColumn)
{
    //queryModel->setAlignRightColumn(alignRightColumn);
}

void DbPage::setInsertColumnIndex(int insertColumnIndex)
{
    this->insertColumnIndex = insertColumnIndex;
}

void DbPage::setInsertColumnName(const QString &insertColumnName)
{
    this->insertColumnName = insertColumnName;
}

void DbPage::setInsertColumnWidth(int insertColumnWidth)
{
    this->insertColumnWidth = insertColumnWidth;
}

void DbPage::setTimeColumn(int timeColumn,int startTimeColumn )
{
    queryModel->setTimeColumn(timeColumn,startTimeColumn);
}
void DbPage::setStatusColumn(int statusColumn)
{
    queryModel->setStatusColumn(statusColumn);
}

void DbPage::select()
{
    //重置开始索引
    startIndex = 0;
    pageCurrent = 1;

    //假设只有一页
    slot_receiveCount(resultCurrent, 0);



    //开始分页绑定数据前,计算好总数据量以及行数
        if(whereSql.contains("LIKE")){
            likeSql = QString("select * from %1 %2").arg(tableName).arg(whereSql);
        }else{
            likeSql = QString();
        }
        tempSql = QString("select count(%1) from %2 %3").arg(countName).arg(tableName).arg(whereSql);


    //采用线程执行查询复合条件的记录行数
    DbCountThread *dbCountThread = new DbCountThread(this);
    dbCountThread->setSqlDatabase(this->db);
    //绑定查询结果信号槽,一旦收到结果则立即执行
    connect(dbCountThread, SIGNAL(receiveCount(quint32, double)), this, SIGNAL(receiveCount(quint32, double)));
    connect(dbCountThread, SIGNAL(receiveCount(quint32, double)), this, SLOT(slot_receiveCount(quint32, double)));

    //设置数据库连接名称和查询语句,并启动线程
    dbCountThread->setConnName(connName);
    dbCountThread->setSql(tempSql);
    dbCountThread->start();
}
PageWidget.h
#ifndef PAGEWIDGET_H
#define PAGEWIDGET_H

#include <QWidget>
#include <QList>
#include <QToolButton>
#pragma execution_character_set("utf-8")
class QLabel;
class QEvent;

namespace Ui {
    class PageWidget;
}

class PageWidget : public QWidget {
    Q_OBJECT

public:
    explicit PageWidget( QWidget *parent = 0);
    ~PageWidget();

    int getBlockSize() const;
    int getMaxPage() const;
    int getCurrentPage() const;

    // 其他组件只需要调用这两个函数即可

    void setCurrentPage(int currentPage, bool signalEmitted = false); // 修改当前页时调用
public slots:
    void setMaxPage(int maxPage);   // 当总页数改变时调用
protected:
    virtual bool eventFilter(QObject *watched, QEvent *e);

signals:
    void currentPageChanged(int page);
private:
    void pageButtonsClicked();
private:
    Ui::PageWidget *ui;
    int blockSize;
    int maxPage;
    int currentPage;
    QList<QToolButton *> pageLabels;

    void setBlockSize(int blockSize);
    void updatePageLabels();
    void initialize();
};

#endif // PAGEWIDGET_H
PageWidget.cpp
#include "PageWidget.h"
#include "ui_PageWidget.h"

#include <QIntValidator>
#include <QtGlobal>
#include <QHBoxLayout>
#include <QMouseEvent>
#include <QKeyEvent>
#include <QDebug>

PageWidget::PageWidget( QWidget *parent) : QWidget(parent),
    ui(new Ui::PageWidget) {
    ui->setupUi(this);
    setBlockSize(3);
    initialize();

    maxPage = 0;
    setMaxPage(20);
}

PageWidget::~PageWidget() {
    delete ui;
    //delete pageLabels;
}

bool PageWidget::eventFilter(QObject *watched, QEvent *e) {
    if (e->type() == QEvent::MouseButtonRelease) {
        int page = -1;
        if (watched == ui->toolButtonPrevious) {
            if(currentPage == 1){
                page = 1;
            }else{
                page = getCurrentPage() - 1;
            }

        }

        if (watched == ui->toolButtonNext) {
            if(currentPage + 1 >= maxPage){
                page = maxPage;
            }else{
                page = getCurrentPage() + 1;
            }

        }

        for (int i = 0; i < pageLabels.count(); ++i) {
            if (watched == pageLabels.at(i)) {
                page = pageLabels.at(i)->text().toInt();
                pageLabels.at(i)->setProperty("numberBtnClicked",true);
                break;
            }else{
                pageLabels.at(i)->setProperty("numberBtnClicked",false);
            }
            pageLabels.at(i)->setStyle(QApplication::style());
        }


        if (-1 != page) {
            setCurrentPage(page, true);
            emit currentPageChanged(page);

            return true;
        }
    }

//    if (watched == ui->pageLineEdit && e->type() == QEvent::KeyRelease) {
//        QKeyEvent *ke = static_cast<QKeyEvent *>(e);
//        if (ke->key() == Qt::Key_Enter || ke->key() == Qt::Key_Return) {
//            setCurrentPage(ui->pageLineEdit->text().toInt(), true);
//            return true;
//        }
//    }

    return QWidget::eventFilter(watched, e);
}

int PageWidget::getBlockSize() const {
    return blockSize;
}

int PageWidget::getMaxPage() const {
    return maxPage;
}

int PageWidget::getCurrentPage() const {
    return currentPage;
}

void PageWidget::setMaxPage(int page) {
    page = qMax(page, 1);
    ui->labelCurTotal->setText(QString("%1/%2页 ").arg(currentPage).arg(page));
    if (maxPage != page) {
        this->maxPage = page;
        this->currentPage = 1;
        updatePageLabels();
    }
}

void PageWidget::setCurrentPage(int page, bool signalEmitted) {
    page = qMax(page, 1);
    page = qMin(page, maxPage);
    ui->labelCurTotal->setText(QString("%1/%2页 ").arg(currentPage).arg(maxPage));

    //if (page != this->currentPage) {
        this->currentPage = page;
        updatePageLabels();
    //}
}

void PageWidget::setBlockSize(int blockSize) {
    // 为了便于计算, block size 必须是奇数, 且最小为3
    blockSize = qMax(blockSize, 3);
    if (blockSize % 2 == 0) {
        ++blockSize;
    }
    this->blockSize = blockSize;
}

// 初始化页码的labels
// 分成三个部分, 左...中...右
void PageWidget::initialize() {
//    ui->pageLineEdit->installEventFilter(this);
//    ui->pageLineEdit->setValidator(new QIntValidator(1, 10000000, this));

//    ui->toolButtonNext->setProperty("page", "true");
//    ui->toolButtonPrevious->setProperty("page", "true");
    ui->toolButtonNext->installEventFilter(this);
    ui->toolButtonPrevious->installEventFilter(this);

    //pageLabels = new QList<QLabel *>();

    QHBoxLayout *leftLayout = new QHBoxLayout();
    QHBoxLayout *centerLayout = new QHBoxLayout();
    QHBoxLayout *rightLayout = new QHBoxLayout();
    leftLayout->setContentsMargins(9, 0, 0, 0);
    leftLayout->setSpacing(9);
    centerLayout->setContentsMargins(9, 0, 0, 0);
    centerLayout->setSpacing(9);
    rightLayout->setContentsMargins(9, 0, 0, 0);
    rightLayout->setSpacing(9);

    for (int i = 0; i < blockSize * 3; ++i) {
        QToolButton *label = new QToolButton;//(QString::number(i + 1));
        label->setText(QString::number(i + 1));
        label->setProperty("numberBtnClicked",false);
        label->installEventFilter(this);

        pageLabels.append(label);

        if (i < blockSize) {
            leftLayout->addWidget(label);
        } else if (i < blockSize * 2) {
            centerLayout->addWidget(label);
        } else {
            rightLayout->addWidget(label);
        }
    }

    ui->leftPagesWidget->setLayout(leftLayout);
    ui->centerPagesWidget->setLayout(centerLayout);
    ui->rightPagesWidget->setLayout(rightLayout);
}

void PageWidget::updatePageLabels() {
    ui->leftSeparateLabel->hide();
    ui->rightSeparateLabel->hide();

    if (maxPage <= blockSize * 3) {
        for (int i = 0; i < pageLabels.count(); i += 1) {
            QToolButton *label = pageLabels.at(i);

            if (i < maxPage) {
                label->setText(QString::number(i + 1));
                label->show();
            } else {
                label->hide();
            }

            if (currentPage - 1 == i) {
                label->setProperty("numberBtnClicked",true);
            } else {
                label->setProperty("numberBtnClicked",false);
            }
            pageLabels.at(i)->setStyle(QApplication::style());

            //label->setStyleSheet("/**/");
        }
        return;
    }

    // 以下情况为maxPageNumber大于blockSize * 3, 所有的页码label都要显示
    // c 为 currentPage
    // n 为 block size
    // m 为 maxPage

    // 1. c ∈ [1, n + n/2 + 1]: 显示前 n * 2 个, 后 n 个: 只显示右边的分隔符
    // 2. c ∈ [m - n - n/2, m]: 显示前 n 个, 后 n * 2 个: 只显示左边的分隔符
    // 3. 显示[1, n], [c - n/2, c + n/2], [m - 2*n + 1, m]: 两个分隔符都显示

    int c = currentPage;
    int n = blockSize;
    int m = maxPage;
    int centerStartPage = 0;

    if (c >= 1 && c <= n + n / 2 + 1) {
        // 1. c ∈ [1, n + n/2 + 1]: 显示前 n * 2 个, 后 n 个: 只显示右边的分隔符
        centerStartPage = n + 1;
        ui->rightSeparateLabel->show();
    } else if (c >= m - n - n / 2 && c <= m) {
        // 2. c ∈ [m - n - n/2, m]: 显示前 n 个, 后 n * 2 个: 只显示左边的分隔符
        centerStartPage = m - n - n + 1;
        ui->leftSeparateLabel->show();
    } else {
        // 3. 显示[1, n], [c - n/2, c + n/2], [m - n + 1, m]: 两个分隔符都显示
        centerStartPage = c - n / 2;
        ui->rightSeparateLabel->show();
        ui->leftSeparateLabel->show();
    }

    for (int i = 0; i < n; ++i) {
        pageLabels.at(i)->setText(QString::number(i + 1));                     // 前面 n 个
        pageLabels.at(n + i)->setText(QString::number(centerStartPage + i));   // 中间 n 个
        pageLabels.at(3 * n - i - 1)->setText(QString::number(m - i));         // 后面 n 个
    }

    for (int i = 0; i < pageLabels.count(); ++i) {
        QToolButton *label = pageLabels.at(i);
        int page = label->text().toInt();
        if (page == currentPage) {
            label->setProperty("numberBtnClicked", true);
        } else {
            label->setProperty("numberBtnClicked", false);
        }
        pageLabels.at(i)->setStyle(QApplication::style());

        //label->setStyleSheet("/**/");
        label->show();
    }
}

void PageWidget::pageButtonsClicked()
{
    QToolButton *btn = (QToolButton *)sender();
    if(btn == nullptr){
        return;
    }
    int page = -1;
    for (int i = 0; i < pageLabels.count(); ++i) {
        if (btn == pageLabels.at(i)) {
            page = pageLabels.at(i)->text().toInt();

            break;
        }
    }
}

PageWidget.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>PageWidget</class>
 <widget class="QWidget" name="PageWidget">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>309</width>
    <height>23</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
  <property name="styleSheet">
   <string notr="true">

QToolButton[numberBtnClicked=false]{
	border:1px solid #D9D9D9;
	border-radius: 2px;
	background-color: rgb(255, 255, 255);
	color: rgb(0, 0, 0);
}
QToolButton[numberBtnClicked=true]{
	border:1px solid #D9D9D9;
	border-radius: 2px;
	background-color: #3076F6;
	color: rgb(255, 255, 255);
}
QToolButton#toolButtonPrevious{
	border-image: url(:/new/pictrues/images/previous.png);
	border:1px solid #D9D9D9;
	border-radius: 1px;
}
QToolButton#toolButtonNext{
	border-image: url(:/new/pictrues/images/next.png);
	border:1px solid #D9D9D9;
	border-radius: 1px;
}</string>
  </property>
  <layout class="QHBoxLayout" name="horizontalLayout">
   <property name="spacing">
    <number>0</number>
   </property>
   <property name="leftMargin">
    <number>0</number>
   </property>
   <property name="topMargin">
    <number>0</number>
   </property>
   <property name="rightMargin">
    <number>0</number>
   </property>
   <property name="bottomMargin">
    <number>0</number>
   </property>
   <item>
    <spacer name="horizontalSpacer_2">
     <property name="orientation">
      <enum>Qt::Horizontal</enum>
     </property>
     <property name="sizeHint" stdset="0">
      <size>
       <width>40</width>
       <height>20</height>
      </size>
     </property>
    </spacer>
   </item>
   <item>
    <widget class="QLabel" name="labelCurTotal">
     <property name="text">
      <string>0/0</string>
     </property>
    </widget>
   </item>
   <item>
    <widget class="QToolButton" name="toolButtonPrevious">
     <property name="text">
      <string/>
     </property>
    </widget>
   </item>
   <item>
    <widget class="QWidget" name="leftPagesWidget" native="true"/>
   </item>
   <item>
    <widget class="QLabel" name="leftSeparateLabel">
     <property name="toolTip">
      <string>下一页</string>
     </property>
     <property name="text">
      <string>..</string>
     </property>
    </widget>
   </item>
   <item>
    <widget class="QWidget" name="centerPagesWidget" native="true"/>
   </item>
   <item>
    <widget class="QLabel" name="rightSeparateLabel">
     <property name="toolTip">
      <string>下一页</string>
     </property>
     <property name="text">
      <string>..</string>
     </property>
    </widget>
   </item>
   <item>
    <widget class="QWidget" name="rightPagesWidget" native="true"/>
   </item>
   <item>
    <widget class="QToolButton" name="toolButtonNext">
     <property name="text">
      <string/>
     </property>
    </widget>
   </item>
   <item>
    <spacer name="horizontalSpacer">
     <property name="orientation">
      <enum>Qt::Horizontal</enum>
     </property>
     <property name="sizeHint" stdset="0">
      <size>
       <width>45</width>
       <height>20</height>
      </size>
     </property>
    </spacer>
   </item>
  </layout>
 </widget>
 <resources/>
 <connections/>
</ui>
frmdbpage.h
#ifndef FRMDBPAGE_H
#define FRMDBPAGE_H

#include <QWidget>
#include <QSqlDatabase>
#include "dbpage.h"

namespace Ui {
class frmDbPage;
}

class frmDbPage : public QWidget
{
    Q_OBJECT

public:
    explicit frmDbPage(QWidget *parent = 0);
    ~frmDbPage();

    RSqlTableModel *getQueryModel(){return dbPage->getQueryModel();}
    QTableView *tableView();

    void setSqlDatabase(const QSqlDatabase &db){this->db = db;}
    void select(const QString &sql = "where 1=1");
    void setTableName(const QString &tableName){this->tableName = tableName;}
    void setColumnNames(const QList<QString> & columnNames){this->columnNames = columnNames;}
    void setHideColumn(int column);
    void setTimeColumn(int timeColumn,int startTimeColumn = -1);
    void setStatusColumn(int statusColumn = -1);
    void setPageCount(int count);

public slots:
    void slotCurrentPageChanged(int page);
    void slotReceivePage(quint32 pageCurrent, quint32 pageCount, quint32 resultCount, quint32 resultCurrent);
private:
    void initForm();
private:
    Ui::frmDbPage *ui;
    QSqlDatabase db;

    QList<QString> columnNames; //字段名集合
    QList<int> columnWidths;    //字段宽度集合
    DbPage *dbPage;             //数据库翻页类

    QString tableName;          //表名称
    QString countName;          //统计行数字段名称

};

#endif // FRMDBPAGE_H

frmdbpage.cpp

#include "frmdbpage.h"
#include "ui_frmdbpage.h"


frmDbPage::frmDbPage(QWidget *parent) : QWidget(parent), ui(new Ui::frmDbPage)
{
    ui->setupUi(this);
    this->initForm();
}

frmDbPage::~frmDbPage()
{
    delete ui;
}

void frmDbPage::initForm()
{
    tableName = "dws_battery_open_current";
    //countName = "rowid";
    countName = "_rowid";

    //设置需要显示数据的表格和翻页的按钮
    dbPage = new DbPage(this);
    //设置所有列居中显示
    dbPage->setAllCenter(true);
    dbPage->setControl(ui->tableMain, countName);
    ui->pageWidget->hide();
    ui->tableMain->horizontalHeader()->setStretchLastSection(true);
    ui->tableMain->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    //ui->tableMain->verticalHeader()->setDefaultSectionSize(25);
    connect(ui->pageWidget,&PageWidget::currentPageChanged,this,&frmDbPage::slotCurrentPageChanged);
    connect(dbPage,&DbPage::signalPageCount,ui->pageWidget,&PageWidget::setMaxPage);
    connect(dbPage,&DbPage::receivePage,this,&frmDbPage::slotReceivePage);
}

void frmDbPage::setHideColumn(int column)
{
    ui->tableMain->hideColumn(column);
}

void frmDbPage::setTimeColumn(int timeColumn,int startTimeColumn)
{
    dbPage->setTimeColumn(timeColumn,startTimeColumn);
}
void frmDbPage::setStatusColumn(int statusColumn )
{
    dbPage->setStatusColumn(statusColumn);
}

QTableView *frmDbPage::tableView()
{
    return ui->tableMain;
}

void frmDbPage::setPageCount(int count)
{
    dbPage->setResultCurrent(count);
}

void frmDbPage::slotReceivePage(quint32 pageCurrent, quint32 pageCount, quint32 resultCount, quint32 resultCurrent)
{
    //qDebug()<<"pageCount:"<<pageCount;
    if(pageCount > 1){
        ui->pageWidget->show();
    }else{
        ui->pageWidget->hide();
    }
}

void frmDbPage::select(const QString &sql)
{
    dbPage->setSqlDatabase(db);

    //绑定数据到表格
    //QString sql = "where 1=1";
    dbPage->setTableName(tableName);
    dbPage->setOrderSql(QString("%1 %2").arg(countName).arg("asc"));
    dbPage->setWhereSql(sql);

    dbPage->setColumnNames(columnNames);
    dbPage->setColumnWidths(columnWidths);
    dbPage->select();

    ui->pageWidget->setCurrentPage(1);
}

void frmDbPage::slotCurrentPageChanged(int page)
{
    //qDebug()<<"------------------";
    dbPage->slotCurrentPageChanged(page);
}

调用的时候直接在UI上将QWidget提升为frmDbPage就行了。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值