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

Posted

技术标签:

【中文标题】隐藏子小部件时,QGridLayout 未调整大小或重新绘制【英文标题】:QGridLayout not resized nor repainted when child widgets get hidden 【发布时间】:2018-02-02 09:16:01 【问题描述】:

我有一个小部件,其中QVBoxLayout 作为主布局,QGridLayout 作为嵌套在主布局中的子布局。有一个切换按钮,可以显示/隐藏网格布局中的某些小部件。更新可见性后,我想调整(最小化)小部件的大小。但是当子小部件被隐藏时调整大小不能正常工作,小部件大小保持不变,它没有像我预期的那样缩小。此外,小部件未正确重绘,一些坏按钮片段仍然可见。我观察到,如果网格布局是主要布局(即没有垂直布局),则不会发生这种情况,但如果它嵌套在另一个布局中,它的行为就会很奇怪。任何想法如何解决这个问题?

widget.h:

#pragma once

#include <QWidget>

class QGridLayout;
class QPushButton;

class Widget : public QWidget

    Q_OBJECT
public:
    explicit Widget(QWidget *parent = 0);
private:
    void updateVisibility();
    QGridLayout *m_layout;
    QPushButton *m_button;
;

widget.cpp:

#include "widget.h"

#include <QGridLayout>
#include <QLabel>
#include <QPushButton>

Widget::Widget(QWidget *parent) :
    QWidget(parent)

    m_layout = new QGridLayout();
    m_layout->addWidget(new QLabel("Label1"), 0, 0);
    m_layout->addWidget(new QLabel("Label2"), 1, 0);

    m_button = new QPushButton("Visible");
    connect(m_button, &QPushButton::clicked, this, &Widget::updateVisibility);
    m_button->setCheckable(true);
    m_button->setChecked(false);

    auto layout = new QVBoxLayout(this);
    layout->addLayout(m_layout);
    layout->addWidget(m_button);
    updateVisibility();


void Widget::updateVisibility()

    // hide or show Label2
    m_layout->itemAtPosition(1, 0)->widget()->setVisible(m_button->isChecked());
    adjustSize();

之前:

点击按钮2次后:

更新:我将此报告为错误https://bugreports.qt.io/browse/QTBUG-66151,但我想找到一个合适的解决方法,直到它被修复。

【问题讨论】:

【参考方案1】:

无法在带有 Qt 5.5.1 或 Qt 5.9.4 的 Xubuntu 16.04.3 上重现。我确实观察到一些奇怪的行为。如果我将Widget 添加到QMainWindow 并检查按钮,它将忽略主窗口的布局,直到调整主窗口的大小。 如果我使用Widget 作为***窗口,它会在第一次单击时变大,然后再也不会调整大小,除非用户更改窗口大小。

可能的解决方法:

删除adjustSize() 调用,这阻止了我的奇怪行为。 在小部件上调用update()adjustSize() 之后的父级以安排重绘。 (无法测试,因为我没有绘图工具。) 在adjustSize() 之后致电m_layout-&gt;invalidate() 以安排重新布局。修复了我在主窗口中的问题。您也可以在小部件的父级上或在 adjustSize() 之前尝试该调用。

【讨论】:

我尝试了几种组合,但有效的是 m_layout-&gt;invalidate()adjustSize() 之前(而不是之后)被调用。如果你用这个选项更新你的答案,我会接受它,因为你的努力值得。 好吧,这真的很奇怪.. 根据要求更新了 :-) 在我的情况下,我在 QGridLayout 中有一个 QHBoxLayout 并且它没有按预期调整大小。挣扎了几个小时.... adjustSize() 成功了!非常感谢你们!

以上是关于隐藏子小部件时,QGridLayout 未调整大小或重新绘制的主要内容,如果未能解决你的问题,请参考以下文章

Pyqt QMdiSubWindow 使用可变数量的小部件调整大小

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

如何重置QGridLayout中窗口小部件的列跨度?

如何将 QStackedWidget 大小设置为子小部件的最小尺寸?

QScrollArea 搞砸了 QGridLayout:QGridLayout 隐藏并且没有滚动

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