Hiding Qt widget and keeping widget space

In a simple form I made a few buttons and put a horizontal layout. When mouse leaves the area one of the buttons, the last one, should be hided. Using button->hide() it works, but all the buttons are rearranged by the layout manager. What I want is that all other buttons continue in their positions. I tried replacing the widget with a widget place holder and swapping the button and placeholder hide()/show(), calling placeholder->resize(button->size()), but the layout manager don't respect the resize and the placeholder is set with its minimum size. What is the best way to remove a widget and keeping its space?

Answers


In Qt 5.2 it is possible to do the following:

QSizePolicy sp_retain = widget->sizePolicy();
sp_retain.setRetainSizeWhenHidden(true);
widget->setSizePolicy(sp_retain);

I earlier posted the same solution here:

How to make a Qt widget invisible without changing the position of the other Qt widgets?

(which seems to be a duplicate of this question).


Try to embed your widget into a QStackWidget having 2 pages: * your widget(s) on one page * another empty page

Set current qstackwidget page to the empty page when you want to hide your widget. And set it back to your main page to show back your widget(s).


I had the same issue.

I ended up adding a HorizontalSpacer (my layout was horizontal), which I initially set to 0-size and Fixed size policy. Then I used:

if (button_is_shown)
  ui.horizontalSpacer->changeSize(0,0, QSizePolicy::Fixed, QSizePolicy::Fixed);
else
  ui.horizontalSpacer->changeSize(1,1, QSizePolicy::Expanding, QSizePolicy::Fixed);

To fill in the space. Similarly, you could resize the spacer to the size of the button and keep it as Fixed QSizePolicy.


You could try putting the button to hide inside another widget, and try to make the other widget keep its size properly when the button is hidden. This might be a little difficult. A QStackedWidget has been suggested, and might be the way to go... it would be similar to the QWidget wrapper, except sizing might be easier.

Another option you could look at is inserting a spacer for the placeholder, and setting the spacer to a fixed size that is the button's size. (You'll need to update the size when the button's size changes). You should be able to show/hide those in pairs and make it work like you expect.


I would also try installing an event filter that overrides the original paint event, drawing a transparent background, and ignores most of the events that the widget should not respond to when it's invisible (probably all of them, except QResizeEvent). When the widget becomes visible again, remove the event filter.

See QObject::installEventFilter(QObject*) and QObject::removeEventFilter(QObject*).


Try putting the button you want to hide and unhide in another layout. In that layout along with the button put a spacer. Call Button hide and spacer will take over.Spacer takes over hidden button's space. Other buttons continue to occupy same space.


A simple way to do it is to set the miminum size of the place holder widget instead of resizing it. While the size of the widget is not respected by layouts, the minimum size is.


Probably the simplest way to do it is to set maximum size of buttons to their size hint.

button->setMaximumSize(button->sizeHint());

This should keep the visible buttons the same size and not force them to expand when another is hidden. You will need to take care that if you change the text on the buttons, that you reset their maximum size, but you likely only do this in one place anyway. I believe something like this was done in one of the early chapters of the Qt book (but I don't have it in front of me, so I can't point you to the right place).


I don't know if is the best way, but solved this using a QStackedWidget to wrap the button.


Need Your Help

AES Encryption for an NSString on the iPhone

iphone objective-c encryption nsstring aes

Can anybody point me in the right direction to be able to encrypt a string, returning another string with the encrypted data? (I've been trying with AES256 encryption.) I want to write a method which