QTableWidth添加多选框,单行选中多行选中

img

按住鼠标往下拖,前面不会打勾

img


当页面有多个被选中时,点击非序号那一列,那个勾不会变化


void MainWindow::onCellClicked(int row, int column)
{
    // 获取当前行的所有item
    QList<QTableWidgetItem *> items = ui->tableWidget->selectedItems();
    // 遍历所有item,将背景颜色设置为默认颜色
    foreach(QTableWidgetItem *item, items) {
       item->setBackground(QBrush());
    }
    // 如果点击的是第0列
    if (column == 0)
    {
       // 获取第0列的item
       QTableWidgetItem *item = ui->tableWidget->item(row, column);
       // 如果当前选中状态为已选中,则设置为未选中;如果当前选中状态为未选中,则设置为已选中
       if (item->checkState() == Qt::Checked)
       {
            item->setCheckState(Qt::Unchecked);
            // 获取当前行的item数量
            int columnCount = ui->tableWidget->columnCount();
            // 将整行设置为未选中状态
            ui->tableWidget->setRangeSelected(QTableWidgetSelectionRange(row, 0, row, columnCount - 1), false);
       }
       else
       {
            item->setCheckState(Qt::Checked);
            // 获取当前行的item数量
            int columnCount = ui->tableWidget->columnCount();
            // 将整行设置为选中状态
            ui->tableWidget->setRangeSelected(QTableWidgetSelectionRange(row, 0, row, columnCount - 1), true);
       }
    }
    else
    {
       // 获取选中的单元格列表
       QList<QTableWidgetItem*> selectedItems = ui->tableWidget->selectedItems();
       // 获取第0列的item
       QTableWidgetItem *item = ui->tableWidget->item(row, 0);
       // 检查是否有选中的单元格
       if (selectedItems.isEmpty())
       {
            item->setCheckState(Qt::Unchecked);
       }
       else
       {
            item->setCheckState(Qt::Checked);
       }
    }
}

【以下回答由 GPT 生成】

在QTableWidget中添加多选框并实现单行选中和多行选中功能的代码如下所示:

首先,在QTableWidget的构造函数中,设置表格的选择模式为"ExtendedSelection",这将允许使用Ctrl和Shift键进行多行选择:

ui->tableWidget->setSelectionMode(QAbstractItemView::ExtendedSelection);

然后,为了实现拖动选择多行时显示勾选框的功能,我们需要重载QTableWidget的mouseMoveEvent和paintEvent方法。在mouseMoveEvent中,我们跟踪鼠标的移动并绘制一个覆盖在选中行上方的矩形框,以模拟勾选框的效果。在paintEvent中,我们将实际的勾选框绘制在选中行上。

void MainWindow::mouseMoveEvent(QMouseEvent *event)
{
    QTableWidget::mouseMoveEvent(event);

    if (event->buttons() & Qt::LeftButton) {
        int rows = ui->tableWidget->rowCount();
        int rowHeight = ui->tableWidget->rowHeight(0);
        int mouseY = event->pos().y();
        int startIndex = mouseY / rowHeight;
        int endIndex = qMin((mouseY + rowHeight) / rowHeight, rows - 1);

        if (startIndex != endIndex) {
            updateSelectedRange(startIndex, endIndex);
        }
    }
}

void MainWindow::paintEvent(QPaintEvent *event)
{
    QTableWidget::paintEvent(event);

    if (isSelecting) {
        QPainter painter(viewport());

        int rows = ui->tableWidget->rowCount();
        int rowHeight = ui->tableWidget->rowHeight(0);
        int y1 = selectingStartIndex * rowHeight;
        int y2 = selectingEndIndex * rowHeight + rowHeight;

        painter.setPen(QPen(Qt::darkBlue, 2));
        painter.setBrush(QBrush(Qt::blue, Qt::NoBrush));
        painter.drawRect(0, y1, width(), y2 - y1);
    }
}

void MainWindow::updateSelectedRange(int startIndex, int endIndex)
{
    isSelecting = true;
    selectingStartIndex = startIndex;
    selectingEndIndex = endIndex;

    ui->tableWidget->clearSelection();
    ui->tableWidget->setRangeSelected(QTableWidgetSelectionRange(startIndex, 0, endIndex, ui->tableWidget->columnCount() - 1), true);

    update();
}

最后,我们重写QTableWidget的keyPressEvent方法,以实现点击非序号那一列时改变选中行的勾选状态的功能,同时也包括了单行选中的逻辑:

void MainWindow::keyPressEvent(QKeyEvent *event)
{
    QTableWidget::keyPressEvent(event);

    int currentRow = ui->tableWidget->currentRow();
    int currentColumn = ui->tableWidget->currentColumn();

    if (currentRow != -1 && currentColumn != 0) {
        QTableWidgetItem *item = ui->tableWidget->item(currentRow, 0);

        if (item) {
            if (item->checkState() == Qt::Checked) {
                item->setCheckState(Qt::Unchecked);
            } else {
                item->setCheckState(Qt::Checked);
            }
        }
    }
}

请注意,以上是一种可能的解决方案,根据你的具体需求和使用的Qt版本,可能需要进行适当的调整和优化。


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

。。。你的问题是什么,你想达到什么样的效果?