如何避免 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_layout
从 QStackedLayout
更改为 QVBoxLayout
类型,一切都会开始正常工作。
所以在我看来,QStackedLayout
尊重隐藏小部件的高度,这是我不希望的。有什么想法可以克服这个问题吗?
代码如下:
main.cpp
int main(int argc, char* argv[])
QApplication app(argc, argv);
main_widget w;
w.setFixedSize(400, 400);
w.show();
return app.exec();
main_widget.h
#include <QWidget>
#include <QLabel>
#include <QStackedLayout>
#include <QVBoxLayout>
#include <QPushButton>
class main_widget : public QWidget
Q_OBJECT
public:
main_widget();
;
main_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应用程序中的控制台窗口?