#include "panels/chart/TablePager.hpp" #include #include #include #include #include #include #include #include namespace geopro::app { namespace { // 每页条数选项(实测原版 vxe-pager 下拉:50/100/500/1000,默认 50)。 const int kPageSizes[] = {50, 100, 500, 1000}; constexpr int kPagerCount = 7; // 页码窗口(>此值用 … 折叠,对齐 vxe 默认) constexpr int kJumpStep = 5; // 点击 … 的跳页步长 // 分页器样式:常态不设字色(跟随主题/全局样式表);边框用半透明灰(两主题通用); // hover/选中页用强调蓝 #409EFF(与 DataTableView 开关同色)。 const char* kPagerQss = R"( QToolButton { border: 1px solid rgba(128,128,128,0.35); border-radius: 3px; padding: 1px 6px; min-width: 16px; min-height: 20px; background: transparent; } QToolButton:hover:enabled { color: #409EFF; border-color: #409EFF; } QToolButton[active="true"] { color: #409EFF; border-color: #409EFF; font-weight: bold; } QToolButton:disabled { color: rgba(128,128,128,0.55); } )"; } // namespace TablePager::TablePager(QWidget* parent) : QWidget(parent) { setStyleSheet(QString::fromUtf8(kPagerQss)); auto* lay = new QHBoxLayout(this); lay->setContentsMargins(8, 6, 8, 6); lay->setSpacing(6); lay->addStretch(1); // 右对齐 prevBtn_ = new QToolButton(this); prevBtn_->setText(QStringLiteral("‹")); prevBtn_->setCursor(Qt::PointingHandCursor); connect(prevBtn_, &QToolButton::clicked, this, [this] { emit pageRequested(pageNo_ - 1, pageSize_); }); lay->addWidget(prevBtn_); numHost_ = new QWidget(this); numLay_ = new QHBoxLayout(numHost_); numLay_->setContentsMargins(0, 0, 0, 0); numLay_->setSpacing(6); lay->addWidget(numHost_); nextBtn_ = new QToolButton(this); nextBtn_->setText(QStringLiteral("›")); nextBtn_->setCursor(Qt::PointingHandCursor); connect(nextBtn_, &QToolButton::clicked, this, [this] { emit pageRequested(pageNo_ + 1, pageSize_); }); lay->addWidget(nextBtn_); auto* gotoLabel = new QLabel(QStringLiteral("前往"), this); lay->addWidget(gotoLabel); jumpEdit_ = new QLineEdit(this); jumpEdit_->setFixedWidth(40); jumpEdit_->setAlignment(Qt::AlignCenter); jumpValidator_ = new QIntValidator(1, 1, jumpEdit_); jumpEdit_->setValidator(jumpValidator_); connect(jumpEdit_, &QLineEdit::returnPressed, this, [this] { bool ok = false; int p = jumpEdit_->text().toInt(&ok); const int pc = pageCount(); if (!ok) { jumpEdit_->setText(QString::number(pageNo_)); return; } p = std::min(std::max(1, p), std::max(1, pc)); if (p == pageNo_) { jumpEdit_->setText(QString::number(pageNo_)); return; } emit pageRequested(p, pageSize_); }); lay->addWidget(jumpEdit_); lay->addWidget(new QLabel(QStringLiteral("页"), this)); sizeCombo_ = new QComboBox(this); for (int s : kPageSizes) sizeCombo_->addItem(QStringLiteral("%1条/页").arg(s), s); connect(sizeCombo_, &QComboBox::activated, this, [this](int i) { emit pageRequested(1, sizeCombo_->itemData(i).toInt()); // 改每页条数 → 回第 1 页 }); lay->addWidget(sizeCombo_); totalLabel_ = new QLabel(this); lay->addWidget(totalLabel_); setState(0, 1, pageSize_); } int TablePager::pageCount() const { if (pageSize_ <= 0) return 1; return std::max(1, (total_ + pageSize_ - 1) / pageSize_); } void TablePager::setState(int total, int pageNo, int pageSize) { total_ = std::max(0, total); if (pageSize > 0) pageSize_ = pageSize; const int pc = pageCount(); pageNo_ = std::min(std::max(1, pageNo), pc); prevBtn_->setEnabled(pageNo_ > 1); nextBtn_->setEnabled(pageNo_ < pc); jumpValidator_->setTop(pc); { QSignalBlocker b(jumpEdit_); jumpEdit_->setText(QString::number(pageNo_)); } { QSignalBlocker b(sizeCombo_); int idx = sizeCombo_->findData(pageSize_); if (idx < 0) { // 非预设条数(兜底):补一项再选中 sizeCombo_->addItem(QStringLiteral("%1条/页").arg(pageSize_), pageSize_); idx = sizeCombo_->findData(pageSize_); } sizeCombo_->setCurrentIndex(idx); } totalLabel_->setText(QStringLiteral("共 %1 条记录").arg(total_)); rebuildNumbers(); } void TablePager::rebuildNumbers() { // 清空旧页码按钮。 while (QLayoutItem* it = numLay_->takeAt(0)) { if (QWidget* w = it->widget()) w->deleteLater(); delete it; } const int pc = pageCount(); auto addNum = [this](int p, bool active) { auto* b = new QToolButton(numHost_); b->setText(QString::number(p)); b->setCursor(Qt::PointingHandCursor); b->setProperty("active", active); b->setEnabled(!active); // 当前页不可再点 connect(b, &QToolButton::clicked, this, [this, p] { emit pageRequested(p, pageSize_); }); numLay_->addWidget(b); }; auto addDots = [this](int target) { auto* b = new QToolButton(numHost_); b->setText(QStringLiteral("...")); b->setCursor(Qt::PointingHandCursor); connect(b, &QToolButton::clicked, this, [this, target] { emit pageRequested(target, pageSize_); }); numLay_->addWidget(b); }; if (pc <= kPagerCount) { for (int p = 1; p <= pc; ++p) addNum(p, p == pageNo_); return; } // 折叠窗口:首页 [ … ] 中段(当前±2) [ … ] 末页。 addNum(1, pageNo_ == 1); int left = pageNo_ - 2; int right = pageNo_ + 2; if (left < 2) { left = 2; right = 5; } if (right > pc - 1) { right = pc - 1; left = pc - 4; } if (left > 2) addDots(std::max(1, pageNo_ - kJumpStep)); for (int p = left; p <= right; ++p) addNum(p, p == pageNo_); if (right < pc - 1) addDots(std::min(pc, pageNo_ + kJumpStep)); addNum(pc, pageNo_ == pc); } } // namespace geopro::app