Qt - 在 QTableWidget 中添加一行时出现奇怪的访问冲突
Qt - Strange access violation while adding a row in 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 个单元格以显示第二行,然后我删除 3 个单元格以删除之前创建的第二行,然后我再次添加 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();
}
非常感谢 Adversus。
我完全是 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 个单元格以显示第二行,然后我删除 3 个单元格以删除之前创建的第二行,然后我再次添加 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();
}
非常感谢 Adversus。