Important: Please read the Qt Code of Conduct -

Window widget expanding to both sides

  • I want to shrink and expand a QWidget in both directions (say, from center to right and left). I can programatically resize the widget and then move it in the opposite direction by half the resize value but that causes terrible flickering (even if I set updatesEnabled to false before resizing and moving). As an option, I could increment the widget size by 1 if it was possible to shrink or expand a widget from both right and left sides. Right now if I change the size of the widget it grows (or shrinks) only from the right side. Is it possible to change size while locking the widget at the right side?

  • Moderators

    @deisik I'm pretty confused based on your description. If you could show with an image or explain it a bit clearer we should be able to help.

    My initial though is just use a spacer in your layout to squish it on the side you don't want expanding. But then I realized you may not even be using a layout for your widget.

    So I'll wait to see what you actually need before I offer some solutions. :)

  • @ambershark

    I'm changing the size of a widget (which is a window) since controls inside this window are expanding to fit their contents. I'm only making it wider or narrower (i.e. change only the window's width). But whenever I change its width (programatically), the window grows only to the right. I want it to grow in both directions, to the left and to the right from the center. I can somewhat emulate this functionality by moving the widget at first to the left by 5 pixels (if I want to increase its width by, say, 10 pixels), and then resizing it by 10 pixels. But this produces flickering at window edges. If there is no such way (to make the window expand in both directions at once), I could increase its width by 1 pixel to the right and to the left alternately until I get the desired width. But for that I should know how to make the window grow from right to left, i.e. increase in width at the left side (by default it increases only at the right side)

  • Lifetime Qt Champion


    Did you try with setGeometry

    it will set both position and size in one go. so that might prevent the flickering.

    I assume i understand you correctly and u want a resize where BOTH left and right are increased as some
    drawing apps can do.

  • @mrjj

    setGeometry() doesn't work as intended, it moves the window but it doesn't change its width since the window keeps its minimum size (which it should). So the only way to actually change the window width is to change it by using setMinimumWidth(). In this way, I still have to first move the window and then change its minimum width (but that produces flickering)

    In fact, I don't want both sides to get increased in some form of animation, I just want to avoid flickering when window is expanded or shrunk to its final width with its center remaining in the same position (+/-1 pixel)

  • It seems that I have managed to employ setGeometry() in a useful way by calling setMinimumWidth() with the new smaller width of the window before calling setGeometry() when I need to shrink the window, and by calling setMaximumWidth() with the new bigger width and then calling setGeometry() when I want the window to grow. Flickering noticeably diminished, so I think I can safely mark this question as solved

  • Moderators

    @deisik Another thing you can try is to use an animation to change the size of the window. This will prevent the flicker. Or at least make it nice looking. ;)

    Qt has some really nice animation ability you'd specifically want QPropertyAnimation to animate on size and position properties.

  • @ambershark

    I have already got rid of flickering completely by resizing the window in a cycle by just one pixel at a time and then calling repaint() after each iteration. Expanding window works like a charm (no flickering whatever), but shrinking the top window leaves black vertical bars on the background (it doesn't get repainted in the process) at the sides of the window until the window is fully resized (then they vanish). How can I get rid of the them (without explicitly calling repaint() on the background widgets)? When I manually resize the window with mouse, the background get updated in real time, so there should be a way

  • Moderators

    @deisik My guess here is that you are sending too many messages to the event queue so the background widgets basically get starved while you resize. You can slow down your messages or just explicitly allow other messages to be processed during your resizing.

    You really should check out that property animation though. It does exactly what you want but without having to send 100 messages to resize a window. ;)

  • @ambershark

    I'm not sure that the underlying widgets will get updated if I use QPropertyAnimation for resizing widgets. Can you guarantee that , i.e. they will be receiving the update signals when I shrink the top window using this method (I just don't want to waste my time only to get back to square one)? I remember some method which allowed using bitmaps from memory (i.e. not actual redrawing) for updating certain regions that get exposed during some resize operations. Can anyone chime in on this?

  • Moderators

    @deisik Yea the animation just animates the change in the window properties. It doesn't change how those property changes work. So the resize will affect the contained widgets just like any other resize without animation.

    But don't get me wrong if you have a working solution and don't want to try to find a more efficient one then don't worry about it. If you have time you may want to branch your code and play with the property animation to see if it can make it more fluid for you. Plus it will look cool. Then if it works and you like it, merge it back into your master branch, or just nuke the feature branch if you don't like the animation.

  • @ambershark

    I am talking about the widgets that are not part of the resized window. If I shrink the window the areas that were covered by this widow become exposed. Will they get updated in real time? That's the issue I have now. The widgets that were hidden are not updated during the resize operation. Their parts (from left and right) are shown as black bars until the resize operation is over. I can update them by sending signals to them but it is slow because whole widget gets updated while I need updated only a small part of it which becomes visible during the resize operation

    I'm not sure that QPropertyAnimation will update them either

  • Moderators

    @deisik said in Window widget expanding to both sides:

    I'm not sure that QPropertyAnimation will update them either

    Yea I'm not sure either. Only way to find out is to try. I didn't realize you were talking about underneath widgets. They should get updated though on my sizing/animating windows I don't see any "black bars". So I'd give it about an 80% change of working. ;)

Log in to reply