如何避免 QStackedLayout 中包含隐藏的 QWidget 高度?

Posted

技术标签:

【中文标题】如何避免 QStackedLayout 中包含隐藏的 QWidget 高度?【英文标题】:How to avoid hidden QWidget height included in QStackedLayout? 【发布时间】:2020-08-28 17:50:49 【问题描述】:

我遇到了这种情况,我已经为此苦苦挣扎了几个小时:

我有一个主小部件,其布局设置为main_layout,在此之前将3个布局添加到main_layout

    QVBoxLayout (header_app_layout) 第二个 QVBoxLayout (header_loader_layout) QStackBoxLayout (content_layout)

QStackBoxLayout (content_layout) 添加了 2 个子小部件,其中仅显示了 1 个:

    m_content1_widget(显示的小部件) m_content2_widget

我的问题是,content_layout 正在考虑小部件中隐藏的子小部件的高度:m_content1_widget,因此main_widget 高度溢出。 如果我将 content_layoutQStackedLayout 更改为 QVBoxLayout 类型,一切都会开始正常工作。 所以在我看来,QStackedLayout 尊重隐藏小部件的高度,这是我不希望的。有什么想法可以克服这个问题吗? 代码如下:

ma​​in.cpp

int main(int argc, char* argv[])

    QApplication app(argc, argv);
    main_widget w;
    w.setFixedSize(400, 400);
    w.show();
    return app.exec();

ma​​in_widget.h

#include <QWidget>
#include <QLabel>
#include <QStackedLayout>
#include <QVBoxLayout>
#include <QPushButton>

class main_widget : public QWidget

    Q_OBJECT

public:
    main_widget();
;
 

ma​​in_widget.cpp

#include "main_widget.h"

main_widget::main_widget()
    : QWidget(nullptr)

    QVBoxLayout *header_app_layout = new QVBoxLayout();
    QLabel *header_app_label = new QLabel();
    header_app_label->setText(tr("Header"));
    header_app_layout->addWidget(header_app_label);

    QVBoxLayout* header_loader_layout = new QVBoxLayout();
    QLabel* header_loader_label = new QLabel();
    header_loader_label->setText(tr("Header Loader"));
    header_loader_layout->addWidget(header_loader_label);

    QWidget *m_content1_widget = new QWidget();
    QVBoxLayout* content1_layout = new QVBoxLayout(m_content1_widget);
    QPushButton* content1_button1 = new QPushButton(tr("content1_button1"));
    content1_layout->addWidget(content1_button1);
    QPushButton* content1_button2 = new QPushButton(tr("content1_button2"));
    content1_layout->addWidget(content1_button2);
    QPushButton* content1_button3 = new QPushButton(tr("content1_button3"));
    content1_layout->addWidget(content1_button3);
    content1_button2->hide(); //Hidden for now. But it's height is being included
    content1_button3->hide();

    QWidget* m_content2_widget = new QWidget();
    QVBoxLayout* content2_layout = new QVBoxLayout(m_content2_widget);
    QPushButton* content2_button1 = new QPushButton(tr("content2_button1"));
    content2_layout->addWidget(content2_button1);
    QPushButton* content2_button2 = new QPushButton(tr("content2_button2"));
    content2_layout->addWidget(content2_button2);
    QPushButton* content2_button3 = new QPushButton(tr("content2_button3"));
    content2_layout->addWidget(content2_button3);
    content2_button2->hide();
    content2_button3->hide();


    QStackedLayout* content_layout = new QStackedLayout(); //Doesn't work
    //QVBoxLayout *content_layout = new QVBoxLayout(); //Works, but I need it to be of type `QStackedLayout` to show the 2 child widgets conditionally
    content_layout->addWidget(m_content1_widget);
    content_layout->addWidget(m_content2_widget);
    content_layout->setStackingMode(QStackedLayout::StackingMode::StackOne);
    content_layout->setCurrentIndex(0);

    QVBoxLayout* main_layout = new QVBoxLayout;
    main_layout->addLayout(header_app_layout); //Adding a QVBoxLayout
    main_layout->addLayout(header_loader_layout); //Adding another QVBoxLayout
    main_layout->addSpacing(32);
    main_layout->addLayout(content_layout); //Adding the QStackedLayout

    this->setLayout(main_layout);

【问题讨论】:

如果你使用QStackedWidget会出现这种情况吗? 是的,即使使用 QStackedWidget 也会发生 嗯...我没主意了。 请编辑您的问题以提供可用于重现问题的minimal reproducible example。 不幸的是,我不懂 C++(我只使用 PyQt),所以我不能用示例代码给你一个完整的答案(但如果你愿意,如果你知道如何阅读,我可以用 PyQt 添加一个答案并将其移植到 C++)。无论如何,是的,所有基于 QStackedLayout 的小部件总是使用它们的“页面”的 sizeHint,所以最好的解决方案是继承 QStackedLayout (关于这个,更准确的名称,没有“QStackBoxLayout”)并重新实现sizeHint() 所以它只返回当前可见小部件的提示(但请记住在索引更改时调用updateGeometry())。 【参考方案1】:

我能够通过在m_content2_widget 上调用adjustSize 来解决此问题,这消除了m_content2_widget 中隐藏控件占用的空间。

m_content2_widget->adjustSize();

【讨论】:

以上是关于如何避免 QStackedLayout 中包含隐藏的 QWidget 高度?的主要内容,如果未能解决你的问题,请参考以下文章

如何避免在浏览器 JavaScript 库中包含冗余的 Promise 实现?

EF6:如何在 Select 中包含子属性,以便创建单个实例。避免“相同的主键”错误

即使在我的.pro文件中包含“testlib”包(用于qWait())之后,如何避免Qt应用程序中的控制台窗口?

JavaScript:如何隐藏/取消隐藏 <div>

在 HTML 页面中包含隐藏数据以供 javascript 处理

jquery验证器避免句子中包含某些单词