o18_99_1 2023-08-17 00:28 采纳率: 44.4%
浏览 50
已结题

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);
       }
    }
}
  • 写回答

2条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-08-17 02:05
    关注

    【以下回答由 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版本,可能需要进行适当的调整和优化。


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

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 4月4日
  • 创建了问题 8月17日