PDA

View Full Version : Avoiding flickering when dynamically changing content of a widget



ghorwin
17th September 2007, 22:50
In a dialog some options should be made visible or hidden dynamically as a result of an "Advanced" check box. The dialog contains a number of widgets which are in various hierarchical layouts and group boxes.

Now, when a groupbox in the middle of the dialog is hidden or show, the widgets in the dialog tend to jump around a little and even widgets that do not need to be resized because of existing spacers, are temporarily modified.

This effect is clearly visible and quite annoying. Calling setUpdateEnabled(false) for the dialog before the visibility of the groupbox is changed does not help either.

Is there any way to prevent Qt from updating the dialogs widgets until the final layout has been calculated?

Andreas

wysota
18th September 2007, 00:03
Have you tried calling QLayout::activate() or QLayout::update()?

ghorwin
18th September 2007, 12:32
Have you tried calling QLayout::activate() or QLayout::update()?

When should I call these functions? Right after I have shown or hidden the groupbox? And for which layout(s) should I call these functions?

In my problem, also layouts that are not really affected show some transient change.

Thanks for any suggestions!
Andreas

marcel
18th September 2007, 12:41
I don't think manually updating the layout that is the solution.
From what you say the layout gets updated anyway.

Maybe you can play a bit by blocking the signals for the layouts and enable them after you remove/hide the widgets.

One thing is certain: you won't get this behavior if the widgets that are removed are first or last in the dialog.

wysota
18th September 2007, 13:16
I thought of applying the layout BEFORE it is shown. How many widgets are we talking about anyway? 5? 10? 50? You shouldn't experience any noticable flicker with a limited number of widgets.

ghorwin
18th September 2007, 14:14
Well, the dialog contains several overlayed groupboxes which can be alternatively shown and enabled (unfortunately the stack widget won't do the job because it may be necessary to see several groupboxes at the same time). And the number of total widgets and layouts can be around 50 or more.

But even with a small number of widgets, the problem persists. One solution was so far to hide the parent widget of the layout where the change occurred. However, in some case the flicker is still there.

I checked the layout implementation and it seems that when I turn a widget on, the parent layout will get invalidated and posting a RequestLayout event, so does the parent widget and all the layouts above which can result in quite a few layout events to be processed by the layoutengine.

Now, the suggestion with turning of the event signals sounds like a solution. Essentially, what I would want is just one layout-update of the whole dialog and all its widgets.

So, how would I do that? How and where should I disconnect the RequestLayout event?

Andreas

marcel
18th September 2007, 14:22
I think you can forget about my solution because QLayout does not have any (public) signals :).

Maybe if you can post a small example reproducing the problem, I will take a look at it later on.

ghorwin
19th September 2007, 16:26
Marcel (and others who want to see the effect), I attached a short example that illustrates the problem.

Compile, run and then press the buttons 1 and 5 (toggle visibility of a group box) and check/uncheck the advanced box.

You will see in either case a flickering when the layout is redone.

Mind that this is a fairly "lightweight" example of a dialog with about 50 widgets, others have about 150 to 300 widgets. For these cases the layout updating should really be done in the background before the whole thing gets drawn again.

Thanks for any suggestions!
Andreas

jpn
20th September 2007, 09:10
I'd put a stacked widget inside groupBoxCircleSegmentOptions and just switch the page when corresponding toolButton_N is clicked. This way Ok, Cancel and Abort buttons would always stay at same place instead of jumping back and forth.

Btw, check this article: Flicker Be Gone (http://trolltech.com/company/tt/contents/issue_6/flicker)