目录
- 前言
- 1、功能描述
- 2、代码实现
- 2.1 ui文件
- 2.1 头文件
- 2.2 源码文件
- 2.3 设计思路
- 4、示例
- 5、总结
前言
在应用程序开发时经常会遇到数据分页的需求,每一页展示特定数量的数据,通过点击按钮翻页或者输入页码跳转到指定页。 本文介绍一个自定义分页控件,基本上实现了作为一个分页控件该有的功能。
1、功能描述
本分页控件支持显示总页数,支持显示当前页码,支持跳转到指定页,支持上一页和下一页,支持首页和尾页,支持显示每页数量,支持数据总量显示。
2、代码实现
2.1 ui文件
本分页控件采用ui文件来布局内部的组件,具体布局如下图所示:
2.1 头文件
头文件中每个方法都作了注释,一眼就能明白其功能。
#include <QWidget>
namespace Ui {
class ZPageWidget;
}
class ZPageWidget : public QWidget
{
Q_OBJECT
public:
explicit ZPageWidget(QWidget *parent = nullptr);
~ZPageWidget();
/**
* @brief setPageCount 设置总页数
* @param count 总页数
*/
void setPageCount(int count);
int pageCount() const { return m_pageCount; }
/**
* @brief setCurrentPage 设置当前页
* @param page 当前页码
*/
void setCurrentPage(int page);
int currentPage() const{ return m_currentPage; }
/**
* @brief setDataCount 设置数据总量
* @param cnt 数据总量
*/
void setDataCount(int cnt);
int dataCount() const { return m_dataCount; }
/**
* @brief setPerpageDataCount 设置每页数据量
* @param cnt 每页数据量
*/
void setPerpageDataCount(int cnt);
int perpageDataCount() const { return m_perpageDataCount; }
signals:
/**
* @brief sign_pageChanged 页码变化信号
* @param page 当前页码
*/
void sign_pageChanged(int page);
private:
/**
* @brief pageChanged 切换页码
*/
void pageChanged();
private slots:
/**
* @brief slot_previousPageBtnClicked 前一页按钮槽函数
*/
void slot_previousPageBtnClicked();
/**
* @brief slot_nextPageBtnClicked 后一页按钮槽函数
*/
void slot_nextPageBtnClicked();
/**
* @brief slot_firstPageBtnClicked 首页按钮槽函数
*/
void slot_firstPageBtnClicked();
/**
* @brief slot_lastPageBtnClicked 尾页按钮槽函数
*/
void slot_lastPageBtnClicked();
/**
* @brief slot_skipPageBtnClicked 跳转页码按钮槽函数
*/
void slot_skipPageBtnClicked();
private:
Ui::ZPageWidget *ui;
int m_pageCount;
int m_currentPage;
int m_dataCount;
int m_perpageDataCount;
};
2.2 源码文件
ZPageWidget::ZPageWidget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::ZPageWidget)
, m_pageCount(1)
, m_currentPage(1)
{
ui->setupUi(this);
ui->lineEdit->setValidator(new QRegExpValidator(QRegExp("[0-9]+$")));
connect(ui->btn_previous, SIGNAL(clicked()), this, SLOT(slot_previousPageBtnClicked()));
connect(ui->btn_next, SIGNAL(clicked()), this, SLOT(slot_nextPageBtnClicked()));
connect(ui->btn_first, SIGNAL(clicked()), this, SLOT(slot_firstPageBtnClicked()));
connect(ui->btn_last, SIGNAL(clicked()), this, SLOT(slot_lastPageBtnClicked()));
connect(ui->btn_skip, SIGNAL(clicked()), this, SLOT(slot_skipPageBtnClicked()));
}
ZPageWidget::~ZPageWidget()
{
delete ui;
}
void ZPageWidget::setPageCount(int count)
{
m_pageCount = count;
m_pageCount = m_pageCount > 0 ? m_pageCount : 1;
if(m_currentPage > m_pageCount)
{
m_currentPage = m_pageCount;
}
pageChanged();
}
void ZPageWidget::setCurrentPage(int page)
{
m_currentPage = page;
}
void ZPageWidget::setDataCount(int cnt)
{
m_dataCount = cnt;
ui->lb_totalData->setText(QString("%1:%2").arg(QString::fromLocal8Bit("总数")).arg(cnt));
}
void ZPageWidget::setPerpageDataCount(int cnt)
{
m_perpageDataCount = cnt;
ui->lb_perPageData->setText(QString("%1:%2").arg(QString::fromLocal8Bit("每页")).arg(cnt));
}
void ZPageWidget::pageChanged()
{
emit sign_pageChanged(m_currentPage);
ui->lb_pageInfo->setText(QString("%1/%2").arg(m_currentPage).arg(m_pageCount));
}
void ZPageWidget::slot_previousPageBtnClicked()
{
if(m_currentPage > 1)
{
m_currentPage--;
pageChanged();
}
}
void ZPageWidget::slot_nextPageBtnClicked()
{
if(m_currentPage < m_pageCount)
{
m_currentPage++;
pageChanged();
}
}
void ZPageWidget::slot_firstPageBtnClicked()
{
if(m_currentPage != 1)
{
m_currentPage = 1;
pageChanged();
}
}
void ZPageWidget::slot_lastPageBtnClicked()
{
if(m_pageCount != m_currentPage)
{
m_currentPage = m_pageCount;
pageChanged();
}
}
void ZPageWidget::slot_skipPageBtnClicked()
{
int page = ui->lineEdit->text().toInt();
ui->lineEdit->clear();
if(page > 0 && page <= m_pageCount)
{
m_currentPage = page;
pageChanged();
}
}
2.3 设计思路
该分页控件的设计思路比较简单清晰,根据分页控件支持的功能,将一组QWidget控件封装在一起,在各个按钮槽函数中重新计算页码,并将当前页码用信号的方式,传递给使用者,完成页码与数据的同步。
4、示例
下面这个示例代码演示了如何使用该分页控件。分页控件一般与列表或表格结合使用,当页码改变时更新列表或表格中的数据。下面以分页列表为例来展示,新建一个设计师界面类,命名为PageControlTest,ui文件如下图所示:
测试代码:
PageControlTest::PageControlTest(QWidget *parent) :
QWidget(parent),
ui(new Ui::PageControlTest)
{
ui->setupUi(this);
m_dataList << QString::fromLocal8Bit("1") << QString::fromLocal8Bit("2") << QString::fromLocal8Bit("3")
<< QString::fromLocal8Bit("4") << QString::fromLocal8Bit("5") << QString::fromLocal8Bit("6")
<< QString::fromLocal8Bit("7") << QString::fromLocal8Bit("8") << QString::fromLocal8Bit("9")
<< QString::fromLocal8Bit("10") << QString::fromLocal8Bit("11") << QString::fromLocal8Bit("12")
<< QString::fromLocal8Bit("13");
int perpageCnt = 10;
ui->pageWidget->setPerpageDataCount(perpageCnt);
ui->pageWidget->setDataCount(m_dataList.size());
connect(ui->pageWidget, SIGNAL(sign_pageChanged(int)), this, SLOT(slot_pageChanged(int)));
int pageCount = ceil(m_dataList.size() / (double)perpageCnt);
ui->pageWidget->setPageCount(pageCount);
}
void PageControlTest::loadData()
{
int offset = ui->pageWidget->perpageDataCount() * (ui->pageWidget->currentPage() - 1);
QStringList currPageDataList = m_dataList.mid(offset, ui->pageWidget->perpageDataCount());
ui->listWidget->clear();
for (int var = 0; var < currPageDataList.size(); ++var)
{
ui->listWidget->addItem(currPageDataList[var]);
}
}
void PageControlTest::slot_pageChanged(int page)
{
loadData();
}
效果:
5、总结
以上就是本文的所有内容了,本文实现了一个自定义分页控件,并给出一个使用示例。对此有任何疑问欢迎留言讨论!