0
votes

I try to make a own widget for block scanning like a defrag software. I have now a problem with limitation of widgets in QT.

My current approach is:

r = 200 / c = 83

void QScanBoard::setupLayout()
{

    this->setAttribute(Qt::WA_LayoutUsesWidgetRect);
    this->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);

    gridTable = new QGridLayout;

    gridTable->setSpacing(0);
    gridTable->setMargin(0);
    gridTable->setContentsMargins(0, 0, 0, 0);
    gridTable->setSizeConstraint(QLayout::SetFixedSize);

    this->setLayout(gridTable);
}

void QScanBoard::createTiles()
{
    for (unsigned int r = 0; r < m_numRows; ++r)
    {
        m_tiles += QList<QScanTile*>{};
        for (unsigned int c = 0; c < m_numCols; ++c)
        {
            // add a new tile to the row
            m_tiles[r] += new QScanTile({ r, c }, this);
            gridTable->addWidget(m_tiles[r][c], r, c);

        }
    }
    m_tiles[0][0]->setDown(true);

}

QScanTitle is a QPushButton or also a QLabel as sample. I use a QGridLayout to place this widgets on the dialog (widget).

If I use now 200/83 it is fast enough. If I try to set 2000/83 the software will hang. This means with 166000 widgets are too much. But sometimes I need much more.

Any idea how to manage this? Because a widget can only have one parent I cannot add one QPushButton multiple times, I need to create it for each QGridLayout cell a new one.

Can I set a QGridLayout without any widget inside the cells? Just a Background color?

1
If you need 166000 separate visual items in a grid then using QWidgets is probably not the way to go. You should probably look at QGraphicsView/QGraphicsScene instead.G.M.
Why? This will cause that it is not possible to view 2 million records inside a Grid , from a database result. I think a Grid is also just a collection of different widgets for each cell.ingo
A QWidget is a fairly large thing in terms of the resources it uses. As such I suspect any application that has tens of thousands of them (or more) active/visible at any given time will be very resource hungry and sluggish.G.M.

1 Answers

0
votes

As mentioned in the comments, QWidget is to "heavy" an object for this use. While the QGraphicsScene/QGraphicsView combination from the comments will also work, the simple fact of creating hundreds of thousands of objects is going to take noticeable time. I work extensively with the QGraphicsScene mechanism and in many ways, it's fantastic, but this sounds like a fairly simple grid drawing that doesn't seem to need the extra complexity of QGraphicsScene/QGraphicsView.

What I recommend is that you create a new widget, deriving from QWidget, and instead of creating child widgets in a grid, you just paint them yourself. For a simple tiled pattern, it's not very difficult to do, and it will be many times faster than creating individual objects. You have to override QWidget::paintEvent, and create your painting code there. You'll need to look at the QPainter class.

If the user will interact with the individual tiles some way, then you will also need to code those interactions. For instance, instead of implementing a response to a QPushButton click in your current approach, your custom widget would need to handle the mouse events and use the mouse event coordinates to determine which tile the user clicked. Then you can do whatever you need to with that information.