Qt - 在 QTableWidget 中添加行时出现奇怪的访问冲突



我是Qt的新手,但我需要确定我是否可以使用此IDE来创建专业项目。出于这个原因,我使用Visual Studio 2019创建了一个演示项目,并提供的Qt Designer来设计我的用户界面。

我的演示包含一个我使用 QTableWidget 对象创建的网格视图,该对象在设计器中配置了 7 列,我可以通过单击 (+) 和 (-) 按钮动态添加和删除单元格。

以下是添加和删除单元格的代码:

void MainForm::OnAddClicked()
{
const int row    = (m_CellCount / 7);
const int column = (m_CellCount % 7);
// add a new line if required
m_UI.twGridView->setRowCount(row + 1);
QString                 text;
QFont                   font("Segoe UI", 14);
QFontMetrics            metrics(font);
std::unique_ptr<QLabel> pImage(new QLabel());
switch (m_CellCount % 3)
{
case 0:
{
text = metrics.elidedText("This is a very very long device name", Qt::ElideRight, m_UI.twGridView->columnWidth(column) - 10);
pImage->setStyleSheet("image: url(resources/images/Device.png) center center;");
break;
}
case 1:
text = metrics.elidedText("iPod Shuffle Robbie", Qt::ElideRight, m_UI.twGridView->columnWidth(column) - 10);
pImage->setStyleSheet("image: url(resources/images/Shuffle.png) center center;");
break;
case 2:
text = metrics.elidedText("iPad Robbie", Qt::ElideRight, m_UI.twGridView->columnWidth(column) - 10);
pImage->setStyleSheet("image: url(resources/images/iPad.png) center center;");
break;
}
std::unique_ptr<QLabel> pLabel(new QLabel(text));
pLabel->setFixedHeight(20);
pLabel->setAlignment(Qt::AlignLeft | Qt::AlignBottom);
pLabel->setFont(font);
pLabel->setStyleSheet("color: rgb(243, 243, 243);");
std::unique_ptr<QWidget>     pWidget(new QWidget());
std::unique_ptr<QVBoxLayout> pLayout(new QVBoxLayout(pWidget.get()));
pLayout->addSpacing(10);
pLayout->addWidget(pImage.get());
pLayout->addSpacing(10);
pLayout->addWidget(pLabel.get());
pWidget->setLayout(pLayout.get());
pWidget->setStyleSheet("background: none;");
pImage.release();
pLabel.release();
pLayout.release();
m_UI.twGridView->setCellWidget(row, column, pWidget.get());
pWidget.release();
++m_CellCount;
}
void MainForm::OnDelClicked()
{
if (m_CellCount)
{
--m_CellCount;
const int row    = (m_CellCount / 7);
const int column = (m_CellCount % 7);
delete m_UI.twGridView->cellWidget(row, column);
m_UI.twGridView->setRowCount(!column ? row : row + 1);
}
else
{
if (m_UI.twGridView->rowCount())
delete m_UI.twGridView->cellWidget(0, 0);
m_UI.twGridView->setRowCount(0);
}
}

此代码在全球范围内运行良好,并且可以完成工作。但是,由于我无法弄清楚的原因,在执行以下行时,我有时会遇到奇怪的访问违规:

// add a new line if required
m_UI.twGridView->setRowCount(row + 1);

例如,如果我添加 9 个单元格以显示第 2 行,然后我删除 3 个单元格以删除之前创建的第 2 行,然后再次添加 2 个单元格,我在上面提到的行上遇到访问冲突,而第 2 行再次添加。

谁能向我解释我做错了什么?

正如上面@Adversus所说,删除单元格不是一个好主意。将删除行替换为:

m_UI.twGridView->setCellWidget(row, column, NULL);

为我解决了这个问题。

以下是更正后的代码:

void MainForm::OnAddClicked()
{
const int row    = (m_CellCount / 7);
const int column = (m_CellCount % 7);
// add a new line if required
m_UI.twGridView->setRowCount(row + 1);
QString                 text;
QFont                   font("Segoe UI", 14);
QFontMetrics            metrics(font);
std::unique_ptr<QLabel> pImage(new QLabel());
switch (m_CellCount % 3)
{
case 0:
{
text = metrics.elidedText("This is a very very long device name", Qt::ElideRight, m_UI.twGridView->columnWidth(column) - 10);
pImage->setStyleSheet("image: url(resources/images/Device.png) center center;");
break;
}
case 1:
text = metrics.elidedText("iPod Shuffle Robbie", Qt::ElideRight, m_UI.twGridView->columnWidth(column) - 10);
pImage->setStyleSheet("image: url(resources/images/Shuffle.png) center center;");
break;
case 2:
text = metrics.elidedText("iPad Robbie", Qt::ElideRight, m_UI.twGridView->columnWidth(column) - 10);
pImage->setStyleSheet("image: url(resources/images/iPad.png) center center;");
break;
}
std::unique_ptr<QLabel> pLabel(new QLabel(text));
pLabel->setFixedHeight(20);
pLabel->setAlignment(Qt::AlignLeft | Qt::AlignBottom);
pLabel->setFont(font);
pLabel->setStyleSheet("color: rgb(243, 243, 243);");
std::unique_ptr<QWidget>     pWidget(new QWidget());
std::unique_ptr<QVBoxLayout> pLayout(new QVBoxLayout(pWidget.get()));
pLayout->addSpacing(10);
pLayout->addWidget(pImage.get());
pLayout->addSpacing(10);
pLayout->addWidget(pLabel.get());
pWidget->setLayout(pLayout.get());
pWidget->setStyleSheet("background: none;");
pImage.release();
pLabel.release();
pLayout.release();
m_UI.twGridView->setCellWidget(row, column, pWidget.get());
pWidget.release();
++m_CellCount;
}
void MainForm::OnDelClicked()
{
if (m_CellCount)
{
--m_CellCount;
const int row    = (m_CellCount / 7);
const int column = (m_CellCount % 7);
//delete m_UI.twGridView->cellWidget(row, column);
m_UI.twGridView->setCellWidget(row, column, NULL);
m_UI.twGridView->setRowCount(!column ? row : row + 1);
}
else
m_UI.twGridView->clearContents();
}

非常感谢你。

最新更新