Qt - 如何有效地在 QTableWidget 中添加大范围的单元格?
Qt - How to efficiently add a huge range of cells in a QTableWidget?
我完全是 Qt 新手,我需要在 QTableWidget 中添加大量单元格。每个单元格都包含一个自定义小部件,由图像和文本组成。
我使用以下代码添加单元格:
//---------------------------------------------------------------------------
GridView::GridView(QWidget *parent) :
QMainWindow(parent)
{
m_UI.setupUi(this);
m_CellCount = 1000000;
// add a new line if required
m_UI.twGridView->setRowCount((m_CellCount / 7) + 1);
for (int i = 0; i < m_CellCount; ++i)
AddGridItem(i);
}
//---------------------------------------------------------------------------
void GridView::AddGridItem(int index)
{
const int row = (index / 7);
const int column = (index % 7);
QString text;
QFont font("Segoe UI", 14);
QFontMetrics metrics(font);
std::unique_ptr<QLabel> pImage(new QLabel());
switch (index % 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();
}
//---------------------------------------------------------------------------
我的问题是上面的代码对于少量单元格是可以接受的,但是添加大量单元格会破坏性能,这是一种不可接受的方式(即直到几十分钟才能打开视图)。 "huge amount",我说的是大约 1'000'000 个细胞。
在我的网格视图中添加如此多的单元格而不显着破坏性能,同时尊重它们的内容的正确方法是什么?
如果您需要良好的性能,您应该考虑将 QTableView 与您自己的模型一起使用。
好的开始是this tutorial。
您可以尝试的快速修复方法是在添加项目时禁用 QTableWidget
上的 GUI 更新,然后重新启用它们。使用 setUpdatesEnabled
方法执行此操作。
最好的解决方案是改用 QTableView
。您可以先尝试使用 QStandardItemModel
,如果它不够快或使用太多内存,则创建一个自定义模型。但我必须警告,既然你说你是一个 Qt 新手,Qt 模型和模型视图是框架中最复杂的部分,所以准备好做一些研究(确实首先用 QStandardItemModel
创建工作代码作为基线)。
我完全是 Qt 新手,我需要在 QTableWidget 中添加大量单元格。每个单元格都包含一个自定义小部件,由图像和文本组成。
我使用以下代码添加单元格:
//---------------------------------------------------------------------------
GridView::GridView(QWidget *parent) :
QMainWindow(parent)
{
m_UI.setupUi(this);
m_CellCount = 1000000;
// add a new line if required
m_UI.twGridView->setRowCount((m_CellCount / 7) + 1);
for (int i = 0; i < m_CellCount; ++i)
AddGridItem(i);
}
//---------------------------------------------------------------------------
void GridView::AddGridItem(int index)
{
const int row = (index / 7);
const int column = (index % 7);
QString text;
QFont font("Segoe UI", 14);
QFontMetrics metrics(font);
std::unique_ptr<QLabel> pImage(new QLabel());
switch (index % 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();
}
//---------------------------------------------------------------------------
我的问题是上面的代码对于少量单元格是可以接受的,但是添加大量单元格会破坏性能,这是一种不可接受的方式(即直到几十分钟才能打开视图)。 "huge amount",我说的是大约 1'000'000 个细胞。
在我的网格视图中添加如此多的单元格而不显着破坏性能,同时尊重它们的内容的正确方法是什么?
如果您需要良好的性能,您应该考虑将 QTableView 与您自己的模型一起使用。
好的开始是this tutorial。
您可以尝试的快速修复方法是在添加项目时禁用 QTableWidget
上的 GUI 更新,然后重新启用它们。使用 setUpdatesEnabled
方法执行此操作。
最好的解决方案是改用 QTableView
。您可以先尝试使用 QStandardItemModel
,如果它不够快或使用太多内存,则创建一个自定义模型。但我必须警告,既然你说你是一个 Qt 新手,Qt 模型和模型视图是框架中最复杂的部分,所以准备好做一些研究(确实首先用 QStandardItemModel
创建工作代码作为基线)。