Widgets doesn't fit to content after hiding
-
Hey,
I've got a QGroupbox with some widgets. I would like to hide some widgets in some case and show them again. The problem is when I'm hiding widgets the height from the QGroupbox didn't fit to content. I have more space available than I need. When I have more widgets in my Groupbox the space will be more too.
I set the SizePolicy from my Groupbox to minimum and after hiding the widgets I set a new minimumheight and called adjustSize(). But it doesn't worked. I also tried to call resize(minimumSizeHint()) with no solution.
-
Mhm its difficult to figure out what code is relevant but I'll try to paste some snippets together.
//SizePolicy for the Groupbox this->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); void MyGBox::minimizeGBox() { layout->setRowMinimumHeight(2, 0); layout->setRowMinimumHeight(4, 0); //hiding widgets widget1->hide(); widget2->hide(); widget3->hide(); //this->setFixedHeight(120); //this->setMinimumHeight(120); resize(minimumSizeHint()); this->adjustSize(); }
Does this helping a little bit?
-
Hi working with Widgets and sizes is sometimes confusing. The widget will only give information about it's desired size or limitations. How the Widget is displayed is up to the layout set. Or the size of the parent Widget and it's layout situation. Don't blame the widget if it's not the proper size. Check out the layout!
-
@heiopei Hi,I am sorry,I spent more time. I try mybest to come true your function.
main.cpp
#include "widget.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); Widget w; w.show(); return a.exec(); }
widget.h
#ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include <QGroupBox> #include <QPushButton> #include <QVBoxLayout> #include <QGridLayout> namespace Ui { class Widget; } class Widget : public QWidget { Q_OBJECT public: explicit Widget(QWidget *parent = 0); ~Widget(); private slots: void btn1slots(); void btn2slots(); void btn3slots(); private: Ui::Widget *ui; QGroupBox *groupbox; QPushButton *btn1;//I use the button to replace your widget QPushButton *btn2; QPushButton *btn3; QVBoxLayout *layout; }; #endif // WIDGET_H
widget.cpp
#include "widget.h" #include "ui_widget.h" Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); this->groupbox = new QGroupBox(tr("I am groupBox"),this); this->btn1 = new QPushButton(tr("btn1")); this->btn2 = new QPushButton(tr("btn2")); this->btn3 = new QPushButton(tr("btn3")); this->layout = new QVBoxLayout(); layout->addWidget(btn1); layout->addWidget(btn2); layout->addWidget(btn3); groupbox->setLayout(layout); connect(btn1,SIGNAL(clicked(bool)),this,SLOT(btn1slots())); connect(btn2,SIGNAL(clicked(bool)),this,SLOT(btn2slots())); connect(btn3,SIGNAL(clicked(bool)),this,SLOT(btn3slots())); } Widget::~Widget() { delete ui; } void Widget::btn1slots() { btn1->setHidden(true);//hide the btn1 layout->removeWidget(btn1);//adn removeWidget(btn1) from layout groupbox->adjustSize();//adjustSize } void Widget::btn2slots() { btn2->setHidden(true); layout->removeWidget(btn2); groupbox->adjustSize(); } void Widget::btn3slots() { btn1->setHidden(false);//reshow the btn1 and btn2 btn2->setHidden(false); layout->addWidget(btn1); layout->addWidget(btn2); groupbox->adjustSize(); }
oh,I said clear?
-
@joeQ
Wow thank you for your effort. But sadly its still not working. I hide the widgets with setHidden removed it from layout and called adjustSize like in your example. I've got the same result as before. Don't know if its relevant but I'm using a GridLayout.@Jeroentjehome
Mhm do you have any hint? How can I tell my Layout to show the widgets correctly? -
Actually I read this post http://stackoverflow.com/questions/11086801/layout-sizehint-qwidget and tried activate().
I did a output before and after activate() from sizeHint().height and the result was the same. How is it possible? :( -
Okay, finally I solved my problem. In addition to delete the widgets I have to delete and init the layout too. So big thanks to joeQ for his help!
Its workinh like this:
void clearLayout() { deleteLayouts(); deleteWidgets(); initLayouts(); initWidgets(); }
-
I stuck with this problem and it took me a few days of deep debugging to completely understand the problem and figure out how to solve it properly...
Decided to write reply, probably, it will help someone else.When I show some widget, the top-level widget(
QDialog
in my case) extends to fit new content, but when I hide that widget, the size of top-level widget did not change.
After hiding widget, I tried to callresize()
,adjustSize()
,setGeometry()
and other functions, nothing solved the issue.When I show the widget,
QWidgetPrivate::setVisible(true)
callsQLayout::activate()
Synchroneously.
When I hide the widget,QWidgetPrivate::setVisible(false)
post eventQEvent::LayoutRequest
, which performsQLayout::activate()
Asynchroneously.
So, hiding the widget, did not update the layout, and all resize-functions do nothing, until processing events...Qt5Widgets.dll!QWidgetPrivate::setGeometry_sys() Qt5Widgets.dll!QWidget::resize() Qt5Widgets.dll!QWidget::resize() Qt5Widgets.dll!QWidget::setMinimumSize() Qt5Widgets.dll!QWidget::setMinimumSize() Qt5Widgets.dll!QLayout::activate()
That is call-stack when actual
HWND
resize happens. FunctionsetGeometry_sys
calls::MoveWindow
and perform actual resize.
And this function was called when I show some widget, but was not called when I hide it.https://code.woboq.org/qt5/qtbase/src/widgets/kernel/qlayout.cpp.html#_ZN7QLayout8activateEv
https://doc.qt.io/qt-6/qlayout.html#SizeConstraint-enumThere are layout constraits. Default layout constraits says "The main widget's minimum size is set to
minimumSize()
, unless the widget already has a minimum size."
So, with default constraits the widget size can only increase to satisfy the minimum size.
You can tryQLayout::SetMinAndMaxSize
, but be carefull, all the nested widgets should be on-expandible(withoutQSizePolicy::ExpandFlag
), otherwise it will not work.
OR, you can tryQLayout::SetFixedSize
constraints: "The main widget's size is set tosizeHint()
; it cannot be resized at all". this flag works perfectly, with the only limitation, the dialog cannot be resized. -
I tried all sorts of things as well, searched all over, and eventually found this post
https://stackoverflow.com/questions/68303194/why-adjustsize-doesnt-resize-mainwindow-in-qtIn the end all that I needed to do was
ui.centralWidget->adjustSize();
adjustSize();When a widget was hidden, the window would resize to remove the unused space. When the widget was unhidden, the window and layout would resize to make space for the widget. This was done with Qt 6.5.5, but I would guess this would work with earlier versions as well.