QGridLayout 限制中的多个小部件

Posted

技术标签:

【中文标题】QGridLayout 限制中的多个小部件【英文标题】:Multiple Widgets in QGridLayout limitation 【发布时间】:2019-11-21 08:19:50 【问题描述】:

我尝试制作一个自己的小部件,用于像碎片整理软件一样进行块扫描。 我现在遇到了 QT 中小部件限制的问题。

我目前的做法是:

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 是一个 QPushButton 或一个 QLabel 作为示例。我使用 QGridLayout 将此小部件放置在对话框(小部件)上。

如果我现在使用 200/83,它已经足够快了。如果我尝试设置 2000/83,软件会挂起。这意味着 166000 个小部件太多了。但有时我需要更多。

知道如何管理吗?因为一个小部件只能有一个父级,所以我不能多次添加一个 QPushButton,我需要为每个 QGridLayout 单元格创建一个新的。

我可以在单元格内设置一个没有任何小部件的 QGridLayout 吗?只是一种背景颜色?

【问题讨论】:

如果您需要在网格中包含 166000 个单独的视觉项目,那么使用 QWidgets 可能不是可行的方法。你可能应该看看QGraphicsView/QGraphicsScene 为什么?这将导致无法从数据库结果中查看 Grid 内的 200 万条记录。我认为 Grid 也只是每个单元格的不同小部件的集合。 A QWidget 就其使用的资源而言是一个相当大的东西。因此,我怀疑在任何给定时间有数以万计(或更多)活动/可见的应用程序将非常消耗资源且速度缓慢。 【参考方案1】:

正如cmets中提到的,QWidget就是为了这个用途“重”一个对象。虽然来自 cmets 的 QGraphicsScene/QGraphicsView 组合也可以工作,但创建数十万个对象的简单事实将花费大量时间。我广泛使用 QGraphicsScene 机制,在很多方面,它都很棒,但这听起来像是一个相当简单的网格绘图,似乎不需要 QGraphicsScene/QGraphicsView 的额外复杂性。

我建议您创建一个新的小部件,从 QWidget 派生,而不是在网格中创建子小部件,您只需自己绘制它们。对于一个简单的平铺图案来说,做起来并不难,而且比创建单个对象要快很多倍。你必须重写 QWidget::paintEvent,并在那里创建你的绘画代码。您需要查看 QPainter 类。

如果用户将以某种方式与各个图块进行交互,那么您还需要对这些交互进行编码。例如,不是在您当前的方法中实现对 QPushButton 单击的响应,您的自定义小部件将需要处理鼠标事件并使用鼠标事件坐标来确定用户单击了哪个图块。然后,您可以使用该信息做任何您需要的事情。

【讨论】:

以上是关于QGridLayout 限制中的多个小部件的主要内容,如果未能解决你的问题,请参考以下文章

如何将QWidget的背景放在QGridLayout中的其他小部件下

隐藏子小部件时,QGridLayout 未调整大小或重新绘制

将小部件插入 QGridLayout 的问题

QGridLayout 不会返回其所有子小部件

带 Qt 的动态 QGridLayout(适应小部件大小)

如何在 QGridLayout 中设置小部件的顺序