QT 自定义分页控件

Qt 自定义页码控件

一、效果展示

在这里插入图片描述

二、头文件
#ifndef PAGECONTROL_H
#define PAGECONTROL_H
#include <QList>
#include <QLabel>
#include <QWidget>
#include <QLineEdit>
#include <QHBoxLayout>
#include <QPushButton>


class PageControl : public QWidget
{
    Q_OBJECT

public:
    explicit PageControl(QWidget *parent = 0);
    ~PageControl();
    void initPage(int total, int pageNum = 1, int pageSize = 10);
    void setTotal(int total);
    void setCurrentPage(int pageNum = 1);
    void setCurrentPageEmitSignal(int pageNum = 1);
    void setPageSize(int pageSize = 10);

protected:
    virtual bool eventFilter(QObject *watched, QEvent *e);

Q_SIGNALS:
    //页码切换消息
    void pageChanged(int currentPage);

private:
    void initJumpControl();
    void initPageBtnControl();
    void updatePageBtn();
    QPushButton* initPushButton();

private:
    QHBoxLayout *m_pPageHLayout;

    QLabel *m_pTotalLabel;                  //显示总数据条数

    QHBoxLayout *m_pPageBtnHLayout;
    QPushButton *m_pPrePageBtn;             //上一页
    QPushButton *m_pNextPageBtn;            //下一页
    QPushButton *m_pFirstPageBtn;           //首页按钮
    QPushButton *m_pLastPageBtn;            //最后一页按钮
    QPushButton *m_pLeftMoreBtn;            //左边省略号按钮
    bool m_bShowLeftMoreBtn;
    QPushButton *m_pRightMoreBtn;           //右边省略号按钮
    bool m_bShowRightMoreBtn;
    QList<QPushButton*> m_MorePageBtnList;  //中间数字按钮

    //跳转元素控件
    QHBoxLayout *m_pJumpHLayout;
    QLabel *m_pGoToLabel;
    QLineEdit *m_pPageLineEdit;
    QPushButton *m_pGotoBtn;
    QLabel *m_pPageUnitLabel;

    int m_nPageNum;
    int m_nPageSize;
    int m_nPageCount;
    int m_nTotal;
    int m_nMidBtnNum;
};
#endif // PAGECONTROL_H
三、源文件
#pragma execution_character_set("utf-8")
#include "PageControl.h"
#include <QIntValidator>
#include <QStyle>
#include <QDebug>
#include <QEvent>
#include <QKeyEvent>

#ifndef SAFE_DELETE
#define SAFE_DELETE(pObj) {if(pObj != Q_NULLPTR) {delete pObj; pObj = Q_NULLPTR;}}
#endif

PageControl::PageControl(QWidget *parent) : QWidget(parent)
{
    QString qss = QString("")
            + QString("QPushButton{border:1px solid #eeeeee;background:#ffffff;border-radius:5px;font-family:\"Microsoft YaHei\";font-size:13px;}")
            + QString("QPushButton:hover{background: #01048a;color:#ffffff}")
            + QString("QPushButton[currentPage=\"true\"]{background: #01048a;color:#ffffff;border-radius:5px;}")
            + QString("QLabel{font-family:\"Microsoft YaHei\";font-size:13px;}")
            + QString("QLineEdit{border-radius:5px;border:1px solid #eeeeee;font-family:\"Microsoft YaHei\";font-size:13px;}");
    this->setStyleSheet(qss);

    m_pPageHLayout = Q_NULLPTR;
    m_pTotalLabel = Q_NULLPTR;
    m_pPageBtnHLayout = Q_NULLPTR;
    m_pPrePageBtn = Q_NULLPTR;
    m_pNextPageBtn = Q_NULLPTR;
    m_pFirstPageBtn = Q_NULLPTR;           //首页按钮
    m_pLastPageBtn = Q_NULLPTR;            //最后一页按钮
    m_pLeftMoreBtn = Q_NULLPTR;            //左边省略号按钮
    m_pRightMoreBtn = Q_NULLPTR;           //右边省略号按钮
    //跳转元素控件
    m_pJumpHLayout = Q_NULLPTR;
    m_pGoToLabel = Q_NULLPTR;
    m_pPageLineEdit = Q_NULLPTR;
    m_pGotoBtn = Q_NULLPTR;
    m_pPageUnitLabel = Q_NULLPTR;

    m_nPageNum = 1;
    m_nPageSize = 10;

    m_pPageHLayout = new QHBoxLayout();
    m_pPageHLayout->setSpacing(8);
    m_pPageHLayout->setMargin(0);
    this->setLayout(m_pPageHLayout);
    m_pPageHLayout->addStretch(1);
    m_pTotalLabel = new QLabel(this);
    m_pPageHLayout->addWidget(m_pTotalLabel);
    initPageBtnControl();
    initJumpControl();
}

/**
 * @brief PageControl::initPage 初始化
 * @param total 总数据条数
 * @param pageNum 当前页码
 * @param pageSize 单页大小
 */
void PageControl::initPage(int total, int pageNum, int pageSize)
{
    m_nPageCount = (total + pageSize - 1) / pageSize;
    m_nPageSize = pageSize;
    m_pTotalLabel->setText(QString("共%1条").arg(total));
    if(m_nPageCount > 1)
    {
        m_pLastPageBtn->setVisible(true);
        QString maxPageNum = QString::number(m_nPageCount);
        m_pLastPageBtn->setText(maxPageNum);
        m_pLastPageBtn->setFixedWidth(35 + (maxPageNum.length() < 3 ? 0 : maxPageNum.length() - 3) * 12);
    }
    else
    {
        m_pLastPageBtn->setVisible(false);
    }
    if(m_nPageNum > m_nPageCount)
    {
        m_nPageNum = m_nPageCount;
    }
    setCurrentPage(pageNum);
}

/**
 * @brief setCurrentPage 设置当前页码
 * @param pageNum 页码
 */
void PageControl::setCurrentPage(int pageNum)
{
    m_nPageNum = pageNum;
    if(pageNum >= m_nPageCount)
    {
        m_nPageNum = m_nPageCount;
        m_pLastPageBtn->setProperty("currentPage","true");

        m_pLastPageBtn->style()->unpolish(m_pLastPageBtn);
        m_pLastPageBtn->style()->polish(m_pLastPageBtn);
        m_pLastPageBtn->update();
//        m_pLastPageBtn->setStyleSheet("/**/");
        m_pNextPageBtn->setCheckable(false);
        m_pNextPageBtn->setCursor(Qt::ForbiddenCursor);
    }
    else
    {
        m_pLastPageBtn->setProperty("currentPage","false");
//        m_pLastPageBtn->setStyleSheet("/**/");
        m_pLastPageBtn->style()->unpolish(m_pLastPageBtn);
        m_pLastPageBtn->style()->polish(m_pLastPageBtn);
        m_pLastPageBtn->update();
        m_pNextPageBtn->setCheckable(true);
        m_pNextPageBtn->setCursor(Qt::PointingHandCursor);
    }
    if(pageNum <= 1)
    {
        m_nPageNum = 1;
        m_pFirstPageBtn->setProperty("currentPage","true");
//        m_pFirstPageBtn->setStyleSheet("/**/");
        m_pFirstPageBtn->style()->unpolish(m_pFirstPageBtn);
        m_pFirstPageBtn->style()->polish(m_pFirstPageBtn);
        m_pFirstPageBtn->update();
        m_pPrePageBtn->setCheckable(false);
        m_pPrePageBtn->setCursor(Qt::ForbiddenCursor);
    }
    else
    {
        m_pFirstPageBtn->setProperty("currentPage","false");
//        m_pFirstPageBtn->setStyleSheet("/**/");
        m_pFirstPageBtn->style()->unpolish(m_pFirstPageBtn);
        m_pFirstPageBtn->style()->polish(m_pFirstPageBtn);
        m_pFirstPageBtn->update();
        m_pPrePageBtn->setCheckable(true);
        m_pPrePageBtn->setCursor(Qt::PointingHandCursor);
    }
    updatePageBtn();
}

/**
 * @brief setCurrentPage 设置当前页码
 * @param pageNum 页码
 */
void PageControl::setCurrentPageEmitSignal(int pageNum)
{
    emit pageChanged(pageNum);
    setCurrentPage(pageNum);
}

void PageControl::setTotal(int total)
{
    m_pTotalLabel->setText(QString("共%1条").arg(total));
    int pageCount = (total + m_nPageSize - 1) / m_nPageSize;
    if(pageCount != m_nPageCount)
    {
        m_nPageCount = pageCount;
        if(m_nPageNum >= m_nPageCount)
        {
            m_nPageNum = m_nPageCount;
            m_pLastPageBtn->setProperty("currentPage","true");
            m_pLastPageBtn->style()->unpolish(m_pLastPageBtn);
            m_pLastPageBtn->style()->polish(m_pLastPageBtn);
            m_pLastPageBtn->update();
//            m_pLastPageBtn->setStyleSheet("/**/");
            m_pNextPageBtn->setCheckable(false);
            m_pNextPageBtn->setCursor(Qt::ForbiddenCursor);
        }
        else
        {
            m_pLastPageBtn->setProperty("currentPage","false");
//            m_pLastPageBtn->setStyleSheet("/**/");
            m_pLastPageBtn->style()->unpolish(m_pLastPageBtn);
            m_pLastPageBtn->style()->polish(m_pLastPageBtn);
            m_pLastPageBtn->update();
            m_pNextPageBtn->setCheckable(true);
            m_pNextPageBtn->setCursor(Qt::PointingHandCursor);
        }
        if(m_nPageCount > 1)
        {
            m_pLastPageBtn->setVisible(true);
            QString maxPageNum = QString::number(m_nPageCount);
            m_pLastPageBtn->setText(maxPageNum);
            m_pLastPageBtn->setFixedWidth(35 + (maxPageNum.length() < 3 ? 0 : maxPageNum.length() - 3) * 12);
        }
        else
        {
            m_pLastPageBtn->setVisible(false);
        }
        updatePageBtn();
    }
}

/**
 * @brief PageControl::initPageBtnControl 初始化页码按钮部分控件
 */
void PageControl::initPageBtnControl()
{
    m_pPageBtnHLayout = new QHBoxLayout();
    m_pPageBtnHLayout->setSpacing(8);
    m_pPageBtnHLayout->setMargin(0);
    m_pPrePageBtn = initPushButton();
    m_pPrePageBtn->setText("<");
    m_pPageBtnHLayout->addWidget(m_pPrePageBtn);

    m_pFirstPageBtn = initPushButton();
    m_pFirstPageBtn->setText("1");
    m_pPageBtnHLayout->addWidget(m_pFirstPageBtn);

    m_pLeftMoreBtn = initPushButton();
    m_pLeftMoreBtn->setText("...");
    m_pPageBtnHLayout->addWidget(m_pLeftMoreBtn);

    for(int i = 0; i < 5; i++)
    {
        QPushButton *btn = initPushButton();
        m_pPageBtnHLayout->addWidget(btn);
        btn->setCursor(Qt::PointingHandCursor);
        m_MorePageBtnList << btn;
    }

    m_pRightMoreBtn = initPushButton();
    m_pRightMoreBtn->setText("...");
    m_pPageBtnHLayout->addWidget(m_pRightMoreBtn);

    m_pLastPageBtn = initPushButton();
    m_pPageBtnHLayout->addWidget(m_pLastPageBtn);

    m_pNextPageBtn = initPushButton();
    m_pNextPageBtn->setText(">");
    m_pPageBtnHLayout->addWidget(m_pNextPageBtn);

    m_pPageHLayout->addLayout(m_pPageBtnHLayout);
}

/**
 * @brief PageControl::initJumpControl 初始化跳转部分控件
 */
void PageControl::initJumpControl()
{
    m_pJumpHLayout = new QHBoxLayout();
    m_pJumpHLayout->setSpacing(5);
    m_pJumpHLayout->setMargin(0);
    m_pGoToLabel = new QLabel(this);
    m_pGoToLabel->setText(" 前往");
    m_pGoToLabel->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
    m_pGoToLabel->setFixedHeight(35);
    m_pJumpHLayout->addWidget(m_pGoToLabel);

    m_pPageLineEdit = new QLineEdit(this);
    m_pPageLineEdit->setFixedSize(50, 35);
    m_pPageLineEdit->setAlignment(Qt::AlignHCenter);
    m_pPageLineEdit->setValidator(new QIntValidator(1, 10000000, this));
    m_pPageLineEdit->installEventFilter(this);
    m_pJumpHLayout->addWidget(m_pPageLineEdit);

    m_pPageUnitLabel = new QLabel(this);
    m_pPageUnitLabel->setText("页     ");
    m_pPageUnitLabel->setFixedHeight(35);
    m_pJumpHLayout->addWidget(m_pPageUnitLabel);

    m_pPageHLayout->addLayout(m_pJumpHLayout);
}


/**
 * @brief PageControl::updatePageBtn 设置中间数字按钮
 * @param showLeftMore 是否显示左边更多
 * @param showRightMore 是否显示右边更多
 */
void PageControl::updatePageBtn()
{
    m_bShowLeftMoreBtn = false;
    m_bShowRightMoreBtn = false;
    int beginPageNum = 2;
    if(m_nPageCount > 7)
    {
        if(m_nPageNum - 1 < m_nPageCount - m_nPageNum)
        {
            int rightAddIndex = 1;
            if(m_nPageNum > 4)
            {
                m_bShowLeftMoreBtn = true;
                beginPageNum = m_nPageNum - 1;
            }
            else
            {
                rightAddIndex += (4 - m_nPageNum);
                beginPageNum = 2;
            }
            m_bShowRightMoreBtn = true;
        }
        else
        {
            int leftSubIndex = 1;
            if(m_nPageCount - m_nPageNum > 3)
            {
                m_bShowRightMoreBtn = true;
            }
            else
            {
                leftSubIndex += (3 - (m_nPageCount - m_nPageNum));
            }
            m_bShowLeftMoreBtn = true;
            beginPageNum = m_nPageNum - leftSubIndex;
        }
    }
    m_pLeftMoreBtn->setVisible(m_bShowLeftMoreBtn);
    m_pRightMoreBtn->setVisible(m_bShowRightMoreBtn);
    int showBtnSize = m_MorePageBtnList.size() - m_bShowLeftMoreBtn - m_bShowRightMoreBtn;
    for(int i = 0; i < m_MorePageBtnList.size(); i++)
    {
        if(i < showBtnSize && beginPageNum + i < m_nPageCount)
        {
            QString pageNum = QString::number(beginPageNum + i);
            m_MorePageBtnList[i]->setText(pageNum);
            m_MorePageBtnList[i]->setVisible(true);
            m_MorePageBtnList[i]->setFixedWidth(35 + (pageNum.length() < 3 ? 0 : pageNum.length() - 3) * 12);
            if(beginPageNum + i == m_nPageNum)
            {
                m_MorePageBtnList[i]->setProperty("currentPage","true");
            }
            else
            {
                m_MorePageBtnList[i]->setProperty("currentPage","false");
            }
//            m_MorePageBtnList[i]->setStyleSheet("/**/");
            m_MorePageBtnList[i]->style()->unpolish(m_MorePageBtnList[i]);
            m_MorePageBtnList[i]->style()->polish(m_MorePageBtnList[i]);
            m_MorePageBtnList[i]->update();
        }
        else
        {
            m_MorePageBtnList[i]->setVisible(false);
        }
    }
}

QPushButton* PageControl::initPushButton()
{
    QPushButton* pushButton = new QPushButton(this);
    pushButton->setFixedSize(35, 35);
    pushButton->installEventFilter(this);
    return pushButton;
}

/**
 * @brief PageControl::eventFilter
 * @param watched
 * @param e
 * @return
 */
bool PageControl::eventFilter(QObject *watched, QEvent *e)
{
    if (e->type() == QEvent::MouseButtonRelease)
    {
        //上一页按钮被点击
        if(watched == m_pPrePageBtn && m_pPrePageBtn->isCheckable())
        {
            setCurrentPageEmitSignal(m_nPageNum - 1);
        }
        //下一页按钮被点击
        else if(watched == m_pNextPageBtn && m_pNextPageBtn->isCheckable())
        {
            setCurrentPageEmitSignal(m_nPageNum + 1);
        }
        //左边省略号按钮被点击
        else if(watched == m_pLeftMoreBtn)
        {
            setCurrentPageEmitSignal(m_MorePageBtnList.at(1)->text().toInt() - 2);
        }
        //右边省略号按钮被点击
        else if(watched == m_pRightMoreBtn)
        {
            setCurrentPageEmitSignal(m_MorePageBtnList.at(2)->text().toInt() + 2);
        }
        else if(watched == m_pFirstPageBtn)
        {
            setCurrentPageEmitSignal(1);
        }
        else if(watched == m_pLastPageBtn)
        {
            setCurrentPageEmitSignal(m_nPageCount);
        }
        else
        {
            for (int i = 0; i < m_MorePageBtnList.size(); ++i)
            {
                if (watched == m_MorePageBtnList.at(i))
                {
                    setCurrentPageEmitSignal(m_MorePageBtnList.at(i)->text().toInt());
                    break;
                }
            }
        }
    }
    //跳转页敲击回车事件
    if (watched == m_pPageLineEdit && e->type() == QEvent::KeyRelease)
    {
        QKeyEvent *ke = reinterpret_cast<QKeyEvent *>(e);
        if (ke->key() == Qt::Key_Enter || ke->key() == Qt::Key_Return)
        {
            setCurrentPageEmitSignal(m_pPageLineEdit->text().toInt());
            return true;
        }
    }
    return QWidget::eventFilter(watched, e);
}

/**
 * @brief PageControl::~PageControl 析构函数
 */
PageControl::~PageControl()
{
    SAFE_DELETE(m_pTotalLabel);
    SAFE_DELETE(m_pPrePageBtn);
    SAFE_DELETE(m_pNextPageBtn);
    SAFE_DELETE(m_pFirstPageBtn);
    SAFE_DELETE(m_pLastPageBtn);
    SAFE_DELETE(m_pLeftMoreBtn);
    SAFE_DELETE(m_pRightMoreBtn);
    foreach(QPushButton *pBtn, m_MorePageBtnList)
    {
        SAFE_DELETE(pBtn);
    }
    SAFE_DELETE(m_pPageBtnHLayout);

    //跳转元素控件
    SAFE_DELETE(m_pGoToLabel);
    SAFE_DELETE(m_pPageLineEdit);
    SAFE_DELETE(m_pGotoBtn);
    SAFE_DELETE(m_pPageUnitLabel);
    SAFE_DELETE(m_pJumpHLayout);

    SAFE_DELETE(m_pPageHLayout);
}
  • 12
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值