当前位置:   article > 正文

QT 分页控件

qt 分页控件
#ifndef PAGENAVIGATOR_H
#define PAGENAVIGATOR_H

#include <QWidget>
#include <QList>
#include <QLabel>

//class QLabel;
//class QEvent;
//
namespace Ui
{
    class PageNavigator;
}

class PageNavigator : public QWidget
{
    Q_OBJECT

public:
    explicit PageNavigator(int blockSize = 3, QWidget *parent = nullptr);
    ~PageNavigator();

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

    // 其他组件只需要调用这两个函数即可
    void setMaxPage(int page);   // 当总页数改变时调用
    void setCurrentPage(int page, bool signalEmitted = false); // 修改当前页时调用
    int  calMaxPage(int count,int pageNum);

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

signals:
    void currentPageChanged(int page);

private:
    Ui::PageNavigator *ui;
    int m_blockSize;
    int m_maxPage;
    int m_currentPage;
    QList<QLabel *> *m_pageLabels;

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

#endif // PAGENAVIGATOR_H
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
#include "pagenavigator.h"
#include "ui_pagenavigator.h"
#include"QIntValidator"



PageNavigator::PageNavigator(int blockSize/* = 3*/, QWidget *parent/* = nullptr*/)
	: QWidget(parent)
	, ui(new Ui::PageNavigator)
{
    ui->setupUi(this);
    setBlockSize(blockSize);
    initialize();

	m_maxPage = 0;
    setMaxPage(1);
	QString qss = QString(".QLabel[page=\"true\"] { padding: 6px; }")
		+ QString(".QLabel[currentPage=\"true\"] { color: rgb(190, 0, 0);}")
		+ QString(".QLabel[page=\"true\"]:hover { color: white; 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));}");
	this->setStyleSheet(qss);
}

PageNavigator::~PageNavigator()
{
    delete ui;
    delete m_pageLabels;
}

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

        if (watched == ui->nextPageLabel)
		{
			page = getCurrentPage() + 1;
		}

        for (int i = 0; i < m_pageLabels->count(); ++i)
		{
            if (watched == m_pageLabels->at(i))
			{
                page = m_pageLabels->at(i)->text().toInt();
                break;
            }
        }

        if (-1 != page)
		{
			if (!ui->pageLineEdit->text().isEmpty())
			{
				ui->pageLineEdit->clear();
			}
            setCurrentPage(page, true);
            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);
            //setMaxPage(ui->pageLineEdit->text().toInt()); // 测试生成多个页码
            return true;
        }
    }

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

int  PageNavigator::calMaxPage(int count,int pageNum){
    int page=0;
    if(count%pageNum==0){
        page=count/pageNum;
    }else{
        page=(count/pageNum)+1;
    }

    page = qMax(page, 1);

    if (m_maxPage != page)
    {
        m_maxPage = page;
        m_currentPage = 1;
        updatePageLabels();
    }

}
int PageNavigator::getBlockSize() const
{
    return m_blockSize;
}

int PageNavigator::getMaxPage() const
{
    return m_maxPage;
}

int PageNavigator::getCurrentPage() const
{
    return m_currentPage;
}

void PageNavigator::setMaxPage(int page)
{
    page = qMax(page, 1);

    if (m_maxPage != page)
	{
        m_maxPage = page;
        m_currentPage = 1;
        updatePageLabels();
    }
}

void PageNavigator::setCurrentPage(int page, bool signalEmitted/* = false*/)
{
    page = qMax(page, 1);
    page = qMin(page, m_maxPage);

    if (page != m_currentPage)
	{
        m_currentPage = page;
        updatePageLabels();

        if (signalEmitted)
		{
            emit currentPageChanged(page);
        }
    }
}

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

QString pageToText(int page)
{
	return QString::number(page);
}

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

    ui->nextPageLabel->setProperty("page", "true");
    ui->previousPageLabel->setProperty("page", "true");
    ui->nextPageLabel->installEventFilter(this);
    ui->previousPageLabel->installEventFilter(this);

	m_pageLabels = new QList<QLabel *>();

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

    for (int i = 0; i < m_blockSize * 3; ++i)
	{
		QLabel *label = new QLabel(pageToText(i + 1), this);
        label->setProperty("page", "true");
        label->installEventFilter(this);

		m_pageLabels->append(label);

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

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

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

    if (m_maxPage <= m_blockSize * 3)
	{
        for (int i = 0; i < m_pageLabels->count(); i += 1)
		{
            QLabel *label = m_pageLabels->at(i);
            if (i < m_maxPage)
			{
				label->setText(pageToText(i + 1));
                label->show();
            }
			else
			{
                label->hide();
            }

            if (m_currentPage - 1 == i)
			{
                label->setProperty("currentPage", "true");
            }
			else
			{
                label->setProperty("currentPage", "false");
            }

            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 = m_currentPage;
    int n = m_blockSize;
    int m = 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)
	{
		m_pageLabels->at(i)->setText(pageToText(i + 1));                     // 前面 n 个
		m_pageLabels->at(n + i)->setText(pageToText(centerStartPage + i));   // 中间 n 个
		m_pageLabels->at(3 * n - i - 1)->setText(pageToText(m - i));         // 后面 n 个
    }

    for (int i = 0; i < m_pageLabels->count(); ++i)
	{
        QLabel *label = m_pageLabels->at(i);
        int page = label->text().toInt();
        if (page == m_currentPage)
		{
            label->setProperty("currentPage", "true");
        }
		else
		{
            label->setProperty("currentPage", "false");
        }

        label->setStyleSheet("/**/");
        label->show();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297

在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/神奇cpp/article/detail/911740?site
推荐阅读
相关标签
  

闽ICP备14008679号