Search code examples
performancegridviewqt5cell

Qt - How to efficiently add a huge range of cells in a QTableWidget?


I'm completely newbie with Qt, and I need to add a huge range of cells in a QTableWidget. Each cell contains a custom widget, composed by an image and a text.

I use the following code to add the cells:

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

My issue is that the above code is acceptable for a small amount of cells, but adding a huge amount ruins the performances, in a not acceptable way (i.e until several dozen of minutes to open the view). By "huge amount", I'm speaking e.g about 1'000'000 cells.

What is the correct approach to add a such amount of cells in my grid view without ruin dramatically the performances, while respecting their content?


Solution

  • If you need a good performance, you should consider using a QTableView with your own model.

    A good start is this tutorial.