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