Newer
Older
AutoCalibrationXC / QPagedTable / QPagedTable.cpp
#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::setColumns(QList<QMap<QString, QVariant>> colMapList)
{
    QList<QPagedTableColumn> columnList;
    for (QMap<QString, QVariant> colMap : colMapList) {
        QPagedTableColumn col(colMap);
        columnList.append(col);
    }
    setColumns(columnList);
}

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

void QPagedTable::setTableProperty(const char *name, QString value)
{
    ui->table->setProperty(name, value);
}

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::setPageButtonIcons(QStringList iconUrls)
{
    if (iconUrls.size() < 4) {
        return ;
    }

    ui->btnFirst->setIcon(QIcon(iconUrls.at(0)));
    ui->btnPre->setIcon(QIcon(iconUrls.at(1)));
    ui->btnNext->setIcon(QIcon(iconUrls.at(2)));
    ui->btnLast->setIcon(QIcon(iconUrls.at(3)));
}
void QPagedTable::setPageButtonProperty(const char* name, QString value)
{
    ui->wdgtPageBtn->setProperty(name, value);
}
void QPagedTable::setCheckBoxClass(QString className)
{
    checkProperty.insert("class", className);
}

void QPagedTable::setHeaderHeight(int height)
{
    headerHeight = height;
}
void QPagedTable::setDataRowHeight(int height)
{
    dataRowHeight = height;
}


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

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

QList<int> QPagedTable::filterCells(QString colName, QString value)
{
    QList<int> filterList;

    int rowIdx = 0;
    for (QMap<QString, QVariant> rowData : datas) {
        if (rowData.value(colName).toString() == value) {
            filterList.append(rowIdx);
        }
        rowIdx++;
    }

    return filterList;
}

void QPagedTable::setRowSelected(int rowIdx, bool selected)
{
    if (multiCheck != MultiCheckType::NONE) {
        QCheckBox *checkBox = ui->table->cellWidget(rowIdx, 0)->findChild<QCheckBox*>();
        if (checkBox) {
            // 切换 CheckBox 的状态
            checkBox->setCheckState(selected ? Qt::CheckState::Checked : Qt::CheckState::Unchecked);
        }
    }
}

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

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

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

    group->addButton(radio);

    return activeWidget;
}
QWidget * QPagedTable::buildNewLabelWidget(QString text)
{
    QWidget* wdgt = new QWidget(ui->table);
    wdgt->setStyleSheet("QWidget{background: transparent;}");
    QHBoxLayout* lyt = new QHBoxLayout(wdgt);
    QLabel* label = new QLabel(wdgt);
    label->setText(text);
    lyt->addWidget(label, 0, 0);

    return wdgt;
}

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);
}

void QPagedTable::on_table_cellDoubleClicked(int row, int column)
{
    if (multiCheck != MultiCheckType::NONE && doubleClickSelectRow) {
        QTableWidget * tableWidget = qobject_cast<QTableWidget*>(sender());
        if (tableWidget) {
            QCheckBox *checkBox = tableWidget->cellWidget(row, 0)->findChild<QCheckBox*>();
            if (checkBox) {
                // 切换 CheckBox 的状态
                checkBox->toggle();
                emit tableRowSelected(row, checkBox->isChecked());
            }
        }
    }
}