第十四课:采用 Qt 开发翻页/分页/多页窗体组件 您所在的位置:网站首页 电脑浏览器分页怎么弄 第十四课:采用 Qt 开发翻页/分页/多页窗体组件

第十四课:采用 Qt 开发翻页/分页/多页窗体组件

2024-07-13 21:16| 来源: 网络整理| 查看: 265

功能描述:采用 Qt 开发一个翻页/分页/多页的窗体组件,封装为 QWidget 的子类,在你的应用程序中可直接使用。

一、最终演示效果

本次制作的翻页/分页/多页窗体组件是基于 Qt 开发,整个程序封装成 PageWidget 类,继承于 QWidget,在你的应用程序中可直接使用。

主要功能包括:向前一页、向后一页、定位到具体某一页,当前页用红色字体表示, 鼠标悬浮到某一页背景色显示蓝色,样式可根据用户需求进行修改。

二、翻页/分页/多页窗体组件开发

翻页/分页/多页窗体组件主要在 PageWidget.h 和 PageWidget.cpp 中封装了 PageWidget 类,实现了向前一页、向后一页、定位到具体某一页等功能。 

PageWidget.h 文件代码如下:

#ifndef PAGEWIDGET_H #define PAGEWIDGET_H #include #include #include #include #include #include #include #include class PageWidget : public QFrame { Q_OBJECT public: // 翻页显示分成三个部分, 左...中...右,blockSize 表示每部分的标签个数 PageWidget(int blockSize = 3); /** * @brief getBlockSize 获取每部分的标签个数 * @return */ int getBlockSize() const; /** * @brief setBlockSize 设置每部分的标签个数 * @param blockSize 每部分的标签个数,block size 必须是奇数, 且最小为3 */ void setBlockSize(int blockSize); /** * @brief getMaxPage 获取总页数 * @return */ int getMaxPage() const; /** * @brief setMaxPage 设置总页数 * @param maxPage 总页数值 */ void setMaxPage(int maxPage); /** * @brief getCurrentPage 获取当前页数 * @return */ int getCurrentPage() const; /** * @brief setCurrentPage 设置当前页 * @param currentPage 当前页数值 * @param signalEmitted 为 true 时发送 currentPageChanged(int) 信号 */ void setCurrentPage(int currentPage, bool signalEmitted = false); protected: /** * @brief eventFilter 事件过滤器,响应上一页标签和下一页标签的点击事件 * @param watched 发生事件的组件 * @param e 发生事件的类型 * @return */ virtual bool eventFilter(QObject * watched, QEvent * e); signals: /** * @brief currentPageChanged 当前页信号 * @param page 页码 */ void currentPageChanged(int page); private: // 字体 QFont font; // 前一页,"" QLabel * nextPageLabel = nullptr; // 翻页显示分成三个部分, 左...中...右,blockSize 表示每部分的标签个数 int blockSize; // 总页数 int maxPage; // 当前页 int currentPage; // 存储所有的数字标签,总个数为 blockSize*3 QList pageLabels; /** * @brief initialize 标签初始化 */ void initialize(); /** * @brief updatePageLabels 更新显示标签 */ void updatePageLabels(); }; #endif // PAGEWIDGET_H

PageWidget.cpp 文件代码如下:

#include "PageWidget.h" PageWidget::PageWidget(int blockSize): blockSize(blockSize) { setStyleSheet("background-color:#2B2C2E;color:rgba(255,255,255,0.85);"); font = QFont("Times New Roman", 14); font.setBold(true); previousPageLabel = new QLabel; previousPageLabel->setFont(font); previousPageLabel->setAlignment(Qt::AlignCenter); previousPageLabel->setFixedSize(23,23); previousPageLabel->setText(""); nextPageLabel->setStyleSheet("QLabel{color:rgba(255,255,255,0.85); padding:2px;}" "QLabel:hover{color: black; border-radius: 4px; background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(53, 121, 238, 255), stop:1 rgba(0, 202, 237, 255));}"); QHBoxLayout * mainLayout = new QHBoxLayout; mainLayout->setMargin(0); mainLayout->setContentsMargins(0,0,0,0); mainLayout->setSpacing(0); mainLayout->addStretch(1); mainLayout->addWidget(previousPageLabel); mainLayout->addWidget(leftPagesWidget); mainLayout->addWidget(leftSeparateLabel); mainLayout->addWidget(centerPagesWidget); mainLayout->addWidget(rightSeparateLabel); mainLayout->addWidget(rightPagesWidget); mainLayout->addWidget(nextPageLabel); mainLayout->addStretch(1); setLayout(mainLayout); initialize(); setMaxPage(1); } // 获取每部分的标签个数 int PageWidget::getBlockSize() const { return blockSize; } // 设置每部分的标签个数,为了便于计算, block size 必须是奇数, 且最小为3 void PageWidget::setBlockSize(int blockSize) { blockSize = qMax(blockSize, 3); if(blockSize%2 == 0) { ++blockSize; } this->blockSize = blockSize; } // 获取总页数 int PageWidget::getMaxPage() const { return maxPage; } // 设置总页数 void PageWidget::setMaxPage(int page) { page = qMax(page, 1); if(maxPage != page) { this->maxPage = page; this->currentPage = 1; updatePageLabels(); } } // 获取当前页数 int PageWidget::getCurrentPage() const { return currentPage; } // 设置当前页 void PageWidget::setCurrentPage(int page, bool signalEmitted) { page = qMax(page, 1); page = qMin(page, maxPage); if(page != this->currentPage) { this->currentPage = page; updatePageLabels(); if(signalEmitted) { emit currentPageChanged(page); } } } // 事件过滤器,响应上一页标签和下一页标签的点击事件 bool PageWidget::eventFilter(QObject * watched, QEvent * e) { if(e->type() == QEvent::MouseButtonRelease) { int page = -1; // 点击了前一页标签 if(watched == previousPageLabel) { page = getCurrentPage()-1; } // 点击了后一页标签 if(watched == nextPageLabel) { page = getCurrentPage()+1; } // 点击了具体数字的标签 for(int i=0; itext().toInt(); break; } } if(page != -1) { setCurrentPage(page, true); return true; } } return QWidget::eventFilter(watched, e); } // 页码标签初始化,分成三个部分, 左...中...右 void PageWidget::initialize() { previousPageLabel->installEventFilter(this); nextPageLabel->installEventFilter(this); QHBoxLayout * leftLayout = new QHBoxLayout(); leftLayout->setMargin(0); leftLayout->setContentsMargins(0,0,0,0); leftLayout->setSpacing(0); QHBoxLayout * centerLayout = new QHBoxLayout(); centerLayout->setMargin(0); centerLayout->setContentsMargins(0,0,0,0); centerLayout->setSpacing(0); QHBoxLayout * rightLayout = new QHBoxLayout(); rightLayout->setMargin(0); rightLayout->setContentsMargins(0,0,0,0); rightLayout->setSpacing(0); for(int i=0; isetFont(font); label->setAlignment(Qt::AlignCenter); label->setFixedHeight(23); label->setMinimumWidth(23); label->setText(QString::number(i+1)); label->setStyleSheet("QLabel{color:rgba(255,255,255,0.85); padding:2px;}" "QLabel:hover{color: black; border-radius: 4px; background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(53, 121, 238, 255), stop:1 rgba(0, 202, 237, 255));}"); label->installEventFilter(this); pageLabels.append(label); if(iaddWidget(label); } else if(iaddWidget(label); } else { rightLayout->addWidget(label); } } leftPagesWidget->setLayout(leftLayout); centerPagesWidget->setLayout(centerLayout); rightPagesWidget->setLayout(rightLayout); } // 更新显示标签 void PageWidget::updatePageLabels() { leftSeparateLabel->hide(); rightSeparateLabel->hide(); // 总页数小于 blockSize*3,总页数数值之前的 Label 都显示,之后的都隐藏 if(maxPage hide(); } if(currentPage-1 == i) { // 当前页的字体设置为蓝色 label->setStyleSheet("QLabel{color:rgba(255,0,0,0.85); padding:2px;}" "QLabel:hover{color: black; border-radius: 4px; background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(53, 121, 238, 255), stop:1 rgba(0, 202, 237, 255));}"); } else { // 非当前页的字体设置为白色 label->setStyleSheet("QLabel{color:rgba(255,255,255,0.85); padding:2px;}" "QLabel:hover{color: black; border-radius: 4px; background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(53, 121, 238, 255), stop:1 rgba(0, 202, 237, 255));}"); } } return; } // 以下情况为 maxPage 大于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 show(); } else if(c >= m-n-n/2 && c show(); } else { // 3. 显示[1, n], [c - n/2, c + n/2], [m - n + 1, m]: 两个分隔符都显示 centerStartPage = c-n/2; rightSeparateLabel->show(); leftSeparateLabel->show(); } for(int i=0; isetText(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; itext().toInt(); if(page == currentPage) { // 当前页的字体设置为蓝色 label->setStyleSheet("QLabel{color:rgba(255,0,0,0.85); padding:2px;}" "QLabel:hover{color: black; border-radius: 4px; background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(53, 121, 238, 255), stop:1 rgba(0, 202, 237, 255));}"); } else { // 非当前页的字体设置为白色 label->setStyleSheet("QLabel{color:rgba(255,255,255,0.85); padding:2px;}" "QLabel:hover{color: black; border-radius: 4px; background-color: qlineargradient(spread:reflect, x1:0, y1:0, x2:0, y2:1, stop:0 rgba(53, 121, 238, 255), stop:1 rgba(0, 202, 237, 255));}"); } label->show(); } }

如果仅作为翻页/分页/多页组件使用的话,将以上两个文件直接添加到程序中即可使用。为了演示效果,我还写了 Widget.cpp 和 Widget.h 文件,集成翻页/分页/多页组件的使用。

Widget.h 文件代码如下:

#ifndef WIDGET_H #define WIDGET_H #include #include #include #include #include #include #include "PageWidget.h" class Widget : public QWidget { Q_OBJECT public: explicit Widget(); private slots: /** * @brief changeMaxPage 设置总页数 */ void changeMaxPage(); private: // 字体 QFont font; // 总页数标签 QLabel * maxPageLabel; // 总页数输入框 QLineEdit * maxPageLineEdit; // 总页数设置 QPushButton * maxPageBtn; // 分页窗口 PageWidget * pageWidget; }; #endif // WIDGET_H

Widget.cpp 文件代码如下:

#include "Widget.h" #include "PageWidget.h" Widget::Widget() { setStyleSheet("background-color:#2B2C2E;color:rgba(255,255,255,0.85);"); font = QFont("黑体", 12); maxPageLabel = new QLabel; maxPageLabel->setFont(font); maxPageLabel->setAlignment(Qt::AlignCenter); maxPageLabel->setFixedSize(80,23); maxPageLabel->setText("总页数:"); maxPageLineEdit = new QLineEdit; font.setFamily("Times New Roman"); maxPageLineEdit->setFixedHeight(23); maxPageLineEdit->setMinimumWidth(200); maxPageLineEdit->setFont(font); maxPageLineEdit->setAlignment(Qt::AlignCenter); maxPageLineEdit->setValidator(new QIntValidator(1,10000000)); maxPageLineEdit->setStyleSheet("background-color:rgba(255,255,255,0.05); border-radius: 3px; margin:0px;"); connect(maxPageLineEdit, SIGNAL(returnPressed()), this, SLOT(changeMaxPage())); maxPageBtn = new QPushButton; font.setFamily("黑体"); maxPageBtn->setFont(font); maxPageBtn->setText("设置"); maxPageBtn->setStyleSheet("QPushButton{background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 #5EDCF8, stop:0.5 #82E5FB, stop:1 #06C9F4); color:rgb(255,255,255); border-radius:8px; margin:0px;}" "QPushButton:pressed{background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 #c0c0c0, stop:1 #808080); color:rgb(255,255,255); border-radius:8px; margin:0px;}" "QPushButton:disabled{background-color:qlineargradient(spread:pad, x1:0, y1:0, x2:0, y2:1, stop:0 #c0c0c0, stop:1 #808080); color:rgb(255,255,255); border-radius:8px; margin:0px;}"); maxPageBtn->setFixedSize(60,23); connect(maxPageBtn, SIGNAL(clicked()), this, SLOT(changeMaxPage())); pageWidget = new PageWidget; QHBoxLayout * topLayout = new QHBoxLayout(); topLayout->setMargin(0); topLayout->setContentsMargins(0,0,0,0); topLayout->setSpacing(10); topLayout->addWidget(maxPageLabel); topLayout->addWidget(maxPageLineEdit); topLayout->addWidget(maxPageBtn); QVBoxLayout * mainLayout = new QVBoxLayout(); mainLayout->setMargin(0); mainLayout->setContentsMargins(20,20,20,20); mainLayout->setSpacing(20); mainLayout->addLayout(topLayout); mainLayout->addWidget(pageWidget); setLayout(mainLayout); } // 设置总页数 void Widget::changeMaxPage() { pageWidget->setMaxPage(maxPageLineEdit->text().toInt()); pageWidget->setCurrentPage(1); }

完整的代码已经贴上,每个函数的备注写的非常清楚,如有不清楚的地方可以私信我。

如果出现中文乱码的问题,请参考我的另外一篇博客《第十课:Qt 字符编码和中文乱码相关问题》 ,百分百能解决你的问题!



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有