QTableWidget 调用 removeRow 报 segmentation fault

QTableWidget 调用 removeRow 报 segmentation fault

  • QTableWidget 调用 removeRow 报 segmentation fault
    • 问题定位
    • 解决方案
    • 问题代码段

QTableWidget 调用 removeRow 报 segmentation fault

问题定位

报 segmentation fault 可以确定是指针问题,大概率是数组访问越界。经过debug,发现调用QTableWidget::removeRow(int row) 方法时报错,但是传入的row并未发生越界。由此发现了QTableWidget删除行的一些机制。

如果 QTableWidget 删除的行,是当前已经选中的行,即调用 QTableWidget::removeRow(int row) 方法时,传入的 row == QTableWidget::currentRow(); 则会触发 QTableWidget::itemSelectionChanged 信号。

此时在 itemSelectionChanged 信号连接的槽中获取 QTableWidget::currentRow(),会发现currentRow() 变成了 row+1 。

同时在调用 QTableWidget::removeRow(int row) 后,QTableWidget 的总行数已经发生了变化,从原来的 int count = QTableWidget::rowCount() 变成了 count - 1。

所以,如果当前选中行 QTableWidget::currentRow() == count - 2,此时删除当前选中行,在 itemSelectionChanged 信号连接的槽中,当前选中行就变成了 QTableWidget::currentRow() == count - 1,于此同时,QTableWidget::rowCount() 变成了 count - 1。

若此时访问 QTableWidget::item(QTableWidget::currentRow(),0),必报段错误。

解决方案

经过尝试,在调用 QTableWidget::removeRow(int row) 之前,调用 clearSelection() 无法解决这个问题。

可以在itemSelectionChanged 信号连接的槽中调用 QTableWidget::item(QTableWidget::currentRow(),0) 前加越界判断。

问题代码段

#include "ImageManageFrame.h"

ImageManageFrame::ImageManageFrame(QWidget *parent) : QFrame(parent)
{
    uiInit();
    connect(m_tableWidget, &QTableWidget::itemSelectionChanged, this, &ImageManageFrame::slotSelectionChanged);
}

void ImageManageFrame::showImage(QPixmap& pixmap)
{
    m_Label->setPixmap(pixmap);
}

void ImageManageFrame::initItems(QList& list)
{
    m_tableWidget->clearContents();
    m_tableWidget->setRowCount(list.size());
    for (int i = 0; i < list.size(); i++)
    {
        m_tableWidget->setItem(i, 0, new QTableWidgetItem(QString("%1").arg(i+1)));
        m_tableWidget->setItem(i, 1, new QTableWidgetItem(list[i]));
    }
}

void ImageManageFrame::insertItem(int index, QString string)
{
    m_tableWidget->insertRow(index);
    m_tableWidget->setItem(index, 0, new QTableWidgetItem(QString("%1").arg(index+1)));
    m_tableWidget->setItem(index, 1, new QTableWidgetItem(string));
    for (int i = index + 1; i < m_tableWidget->rowCount(); i++)
    {
        m_tableWidget->item(i, 0)->setText(QString::number(i+1));
    }
}

void ImageManageFrame::removeItem(int index)
{
    m_tableWidget->removeRow(index);
    for (int i = index; i < m_tableWidget->rowCount(); i++)
    {
        m_tableWidget->item(i, 0)->setText(QString::number(i+1));
    }
}

void ImageManageFrame::selectIndex(int index)
{
    if (index < m_tableWidget->rowCount())
    {
        m_tableWidget->selectRow(index);
    }
}

void ImageManageFrame::uiInit()
{
    m_tableWidget = new QTableWidget(this);
    m_Label = new QLabel(this);
    m_tableWidget->setGeometry(20, 16, 290, 440);
    m_Label->setGeometry(m_tableWidget->width()+m_tableWidget->x()+14,
                         m_tableWidget->y(),
                         680,
                         m_tableWidget->height());
    m_tableWidget->setColumnCount(2);
    m_tableWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
    m_tableWidget->setFrameShape(QFrame::NoFrame);  // 不显示外边框
    // 设置表头尺寸
    m_tableWidget->verticalHeader()->setDefaultSectionSize(40);
    m_tableWidget->verticalHeader()->setVisible(false);
    m_tableWidget->setColumnWidth(0, 68);
    m_tableWidget->setColumnWidth(1, 220);
    // 设置表头文字
    QStringList headerList;
    headerList.append("序号");
    headerList.append("名称");
    m_tableWidget->setHorizontalHeaderLabels(headerList);
    // 设置表头样式表
    m_tableWidget->horizontalHeader()->setStyleSheet("QHeaderView::section{"
                                                    "font-size:14px;"
                                                    "font-family:'黑体';"
                                                    "color:#333333;"
                                                    "background-color:#EEF7F5;"
                                                    "min-height:40px;"
                                                    "max-height:40px;"
                                                    "border-top: 2px solid #209F84;"
                                                    "border-bottom: 2px solid #209F84;}");
    m_tableWidget->setShowGrid(false);
    m_tableWidget->setSortingEnabled(false);
    m_tableWidget->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    m_tableWidget->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    m_tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
    m_tableWidget->setSelectionMode(QAbstractItemView::SingleSelection);
    QScroller *pScroller = QScroller::scroller(m_tableWidget);
    pScroller->grabGesture(m_tableWidget,QScroller::LeftMouseButtonGesture);
    m_tableWidget->setVerticalScrollMode(QTableWidget::ScrollPerPixel);
    m_tableWidget->setStyleSheet("QTableWidget::item {"
                                    "background-color: #FFFFFF;"
                                    "color: #666666;"
                                    "font-size: 14px;"
                                    "font-family: '黑体';"
                                    "padding: 0px 10px;"
                                    "border-right: 0px solid #ECECEC;"
                                    "border-bottom: 1px solid #ECECEC;"
                                    "}"
                                 "QTableWidget::item::selected {"
                                    "background-color: #EEF7F5;"
                                    "font-size: 14px;"
                                    "font-family: '黑体';"
                                    "padding: 0px 10px;"
                                    "color: #666666;"
                                    "border-right: 0px solid #ECECEC;"
                                    "border-bottom: 1px solid #ECECEC;"
                                    "}");

}

void ImageManageFrame::slotSelectionChanged()
{
    emit signalSelectedIndex(m_tableWidget->currentRow());
}

你可能感兴趣的:(QT,qt,QTableWidget,segmentfault,Segmentation,嵌入式)