Newer
Older
PagedTableDemo / QPagedTable / QPagedTable.cpp
tanyue 27 days ago 7 KB 20250717 添加右键菜单
#include "QPagedTable.h"
#include "ui_QPagedTable.h"

#include <QDebug>

QPagedTable::QPagedTable(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::QPagedTable)
{
    ui->setupUi(this);
}

QPagedTable::~QPagedTable()
{
    delete ui;
}

void QPagedTable::initTableWidget()
{
    // 是否隐藏行号
    ui->table->verticalHeader()->setHidden(!showVerticalHeader);

    // 设置只读
    ui->table->setEditTriggers(static_cast<QAbstractItemView::EditTriggers>(editTrigger));

    // 选中整行
    ui->table->setSelectionBehavior(static_cast<QAbstractItemView::SelectionBehavior>(selectionBehavior));
    ui->table->setFocusPolicy(Qt::NoFocus); // 去除选中虚线框
    ui->table->setAlternatingRowColors(true); // 隔行交替背景色
    ui->table->setShowGrid(false); // 不显示网格线

    ui->table->setFrameStyle(QFrame::NoFrame);

    // 设置行的高度为固定值
    ui->table->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeMode::Fixed);

    ui->table->setContextMenuPolicy(Qt::ContextMenuPolicy::CustomContextMenu);
    menu = new QMenu(ui->table);

    // 临时
    menu->setStyleSheet("QMenu{font-size: 16px;}");
}

void QPagedTable::initTableHeader()
{
    if (multiCheck != MultiCheckType::NONE) {
        QPagedTableColumn colCheck;
        colCheck.name = "check";
        colCheck.text = "";
        colCheck.setWidthType("pixel");
        colCheck.width = 60;
        columns.prepend(colCheck);
        group = new QButtonGroup(ui->table);
    }

    for (QPagedTableColumn col : columns) {
        headerLabels << col.text;

        if (col.widthType == QPagedTableColumn::ColumnWidthType::PIXEL) {
            fixedWidth += col.width;
        }
    }

    ui->table->setColumnCount(columns.size());
    ui->table->setHorizontalHeaderLabels(headerLabels);

    // 设置表头的样式
    QHeaderView * header = ui->table->horizontalHeader();
    header->setMinimumHeight(headerHeight); // 表头高度
    header->setHighlightSections(highlightHeaderSection); // 选中时表头不高亮显示
}

void QPagedTable::adjustTableWidth()
{
    int realWidth = ui->table->width();
    int freeWidth = realWidth - fixedWidth - 2 * frameBorderSize;

    int colIdx = 0;
    for (QPagedTableColumn col : columns) {
        if (col.width == 0) {
            ui->table->hideColumn(colIdx);
            colIdx++;
            continue;
        }

        ui->table->horizontalHeader()->setSectionResizeMode(colIdx, static_cast<QHeaderView::ResizeMode>(col.resizeMode));

        if (col.resizeMode == QHeaderView::ResizeMode::Fixed) {
            if (col.widthType == QPagedTableColumn::ColumnWidthType::PIXEL) {
                ui->table->setColumnWidth(colIdx, col.width);
            } else if (col.widthType == QPagedTableColumn::ColumnWidthType::PERCENT) {
                ui->table->setColumnWidth(colIdx, floor(col.width * freeWidth));
            }
        }

        colIdx++;
    }
}

void QPagedTable::setColumns(QList<QPagedTableColumn> columnList)
{
    columns = columnList;
}

void QPagedTable::setDatas(QList<QMap<QString, QVariant> > pagedDataList)
{
    datas = pagedDataList;
    updateTableList();
}

void QPagedTable::setContextMenuLabels(QStringList menuLabels)
{
    contextMenuLabels = menuLabels;

    connect(ui->table, &QTableWidget::customContextMenuRequested, [=](const QPoint &pos){
        int rowIdx = ui->table->rowAt(pos.y());
        int colIdx = ui->table->columnAt(pos.x());
        if (rowIdx >= 0 && colIdx >= 0) {
            int actionIdx = 0;
            for (QAction * action : menu->actions()) {
                menu->removeAction(action);
            }

            for (QString label : contextMenuLabels) {
                QAction * action = new QAction(label, menu);

                connect(action, &QAction::triggered, [=](){
                    emit contextMenuActionTrigged(actionIdx, rowIdx, colIdx);
                });
                menu->addAction(action);

                actionIdx++;
            }

            menu->exec(ui->table->mapToGlobal(pos));
        }
    });
}

void QPagedTable::setPage(int pageSize, int currentPage, int totalCount, int totalPage)
{
    page.tableRowCount = pageSize;
    page.currentPage = currentPage;
    page.totalCount = totalCount;
    page.totalPage = totalPage;
}
void QPagedTable::setPageSize(int pageSize)
{
    page.tableRowCount = pageSize;
}
void QPagedTable::setTotalCount(int totalCount)
{
    page.calcTotalPage(totalCount);
}


void QPagedTable::setMultiCheckType(MultiCheckType type)
{
    multiCheck = type;
}

QTableWidget * QPagedTable::getTableInstance()
{
    return ui->table;
}

QWidget * QPagedTable::buildNewCheckWidget()
{
    QWidget* activeWidget = new QWidget();
    activeWidget->setStyleSheet("QWidget{background: transparent;}");
    QHBoxLayout* activelayout = new QHBoxLayout(activeWidget);
    QCheckBox* check = new QCheckBox();
    check->setMinimumSize(25, 25);
    check->setMaximumSize(25, 25);
    activelayout->addWidget(check, 0, 0);

    if (multiCheck == MultiCheckType::RADIO) {
        group->addButton(check);
    }

    return activeWidget;
}
QWidget * QPagedTable::buildNewRadioWidget()
{
    QWidget* activeWidget = new QWidget();
    activeWidget->setStyleSheet("QWidget{background: transparent;}");
    QHBoxLayout* activelayout = new QHBoxLayout(activeWidget);
    QRadioButton* radio = new QRadioButton();
    radio->setMinimumSize(25, 25);
    radio->setMaximumSize(25, 25);
    activelayout->addWidget(radio, 0, 0);

    group->addButton(radio);

    return activeWidget;
}

void QPagedTable::updateTableList()
{
    // 清除原有内容
    ui->table->clearContents();
    ui->table->setRowCount(0);

    // 设置行高
    ui->table->verticalHeader()->setDefaultSectionSize(dataRowHeight);

    // 更新页码
    if (page.totalCount == 0)
    {
        ui->labelCurrPage->setText("0");
    } else
    {
        ui->labelCurrPage->setText(QString("%1 / %2 , %3").arg(page.currentPage + 1).arg(page.totalPage).arg(page.totalCount));
    }

    // 更新表格内容
    int rowIdx = 0;
    for (QMap<QString, QVariant> rowData : datas) {
        ui->table->insertRow(rowIdx);

        int colIdx = 0;
        for (QPagedTableColumn col : columns) {
            if (col.name == "check") {
                ui->table->setCellWidget(rowIdx, colIdx, buildNewCheckWidget());
            }

            if (col.name == "index") {
                ui->table->setItem(rowIdx, colIdx, new QTableWidgetItem(QString::number(page.currentPage * page.tableRowCount + rowIdx + 1)));
            } else {
                ui->table->setItem(rowIdx, colIdx, new QTableWidgetItem(rowData.value(col.name).toString()));
            }

            ui->table->item(rowIdx, colIdx)->setTextAlignment(static_cast<Qt::AlignmentFlag>(col.align));

            colIdx++;
        }
        rowIdx++;
    }
}


void QPagedTable::on_btnFirst_clicked()
{
    // 第一页
    page.currentPage = 0;
    emit reloadTablePagedData(page.currentPage);
}

void QPagedTable::on_btnPre_clicked()
{
    // 上一页
    if (page.currentPage > 0)
    {
        page.currentPage = page.currentPage - 1;
    }
    emit reloadTablePagedData(page.currentPage);
}

void QPagedTable::on_btnNext_clicked()
{
    // 下一页
    if (page.currentPage < page.totalPage - 1)
    {
        page.currentPage++;
    }
    emit reloadTablePagedData(page.currentPage);
}

void QPagedTable::on_btnLast_clicked()
{
    // 最后一页
    page.currentPage = page.totalPage - 1;
    emit reloadTablePagedData(page.currentPage);
}