PDA

View Full Version : Stop resizeEvent() from being called multiple times on application startup



pssss
13th September 2011, 22:28
My application reimplements resizeEvent() on some of its widgets. However, when the application starts and show is called on the main window, this event is fired three times. If I change showMaximized() to show() it will get fired 2 times instead of 3. It's not fired if I don't call show or showMaximized().


The problem with this is that even though I don't explicitly do any drawing in the resize event reimplementation, I do set the sizes of some of the child widgets. This causes the interface to sort of wobble on start up.


Could someone please tell me how to avoid this?


Thanks in advance.

high_flyer
14th September 2011, 12:14
With no code, how can we know what is going on in your application?
If you don't call show() do you still get the widgets visible?

pssss
14th September 2011, 12:42
Basically this is it.

in main()


MainWindow window;
window.showMaximized();



Then a child widget of MainWindow of class Widget has resizeEvent() reimplemented:




void Widget::resizeEvent(QResizeEvent *event)
{
nameLabel->setFixedWidth(width()/4);
familyNameLabel->setFixedWidth(width()/4);

QWidget::resizeEvent(event);

}



No, if I don't call show show() the widgets won't be visible. Reimplement resizeEvent() for any widget, then call showMaximized on the MainWindow, you'll see you'll get 3 calls to resizeEvent(). I commented out all the code to make sure it wasn't doing anything that caused more calls but you still get 3.

The reason why I'm not letting the layout handler do what I do in the resizeEvent() method is because Qt doesn't handle font size properly and I've to do it myself.


Thanks again.

high_flyer
14th September 2011, 14:01
you'll see you'll get 3 calls to resizeEvent().
I can't test this at the moment.
Are you sure you are talking about ONE instance of the widget that is being called 3 times?
I'd be surprised if it is so.


because Qt doesn't handle font size properly and I've to do it myself.
I am using Qt for years, and I can't confirm this, quite on the contrary.
What do you mean with "properly"?

pssss
14th September 2011, 18:04
I can't test this at the moment.
Are you sure you are talking about ONE instance of the widget that is being called 3 times?
I'd be surprised if it is so.


I am using Qt for years, and I can't confirm this, quite on the contrary.
What do you mean with "properly"?


Yes, one instance. I can confirm it is so because I only had one qDebug() call in the reimplementation of resizeEvent() for that instance. Removing it from there and testing the other classes, the same thing happens.


I didn't mean to insult Qt, I think it's the best tool out there. I hope you are right, I've been trying to find for ages how to do this. What I meant is that you can't specify font size based on the parent widget's size, i.e. you can't set a font size unit as %. Point, ems and pixels will all take the same space regardless of the parent's size.


At 800x600 I've a really tiny space and I need the font size to be smaller so it fits, on the other hand if the program is at a very high resolution I need the font size to be much bigger so the space doesn't look empty. I've made an ugly solution using QFontMetrics to find out what's the biggest size that fits in a QLabel, I've to call this solution from resizeEvent(). The ideal thing would be that Qt's layout or stylesheet system handled it automatically but it doesn't. I know the problem is not in this ugly solution I made because as I said before, commenting out the code, the event is still triggered 3 times when you call .showMaximized() and 2 times for .show().

EDIT: I forgot to add why editing the label's size manually is necessary in the resizeEvent() and I can't rely on the layout system. The reason is that when resizing to a smaller size for example, when it comes to calculating the new sizes the layout system will use the old big font size to calculate what the label's new size should be, so the label's size won't be proportional to what it should be because its font size hasn't been changed yet.

I've tried every possible combination of sizePolicy, setStretchFactors, etc... but the proportions go out of the window unless I use fixed sizes, I've also installed event filters for each label to see if from there I could make it work. At the end the only solution I've found is using fixed sizes and setting them in the resizeEvent(), however, I get that wobbly effect from the OP.


Thanks for your reply.

high_flyer
15th September 2011, 10:15
I can confirm it is so because I only had one qDebug() call in the reimplementation of resizeEvent() for that instance.
This is not confirming anything.
And you don't have "implementation" for an instance - you have an instance of implementation.
The question is not how many classes you have with this code, but how many *objects* of this class are instantiated!
Its a VERY different thing!
My guess is that you have 3 objects of this class - OR - that resize events are being generated implicitly by some actions you are doing, of you which you are not even aware that they are generating resiteEvents...
I might be wrong of course, but I would first go on this path than to think that Qt calls resizeEvent() 3 times.
One easy test is to write a hello world app, with one widget, and see how many times resiteEvent() is being called.
If its only once, then its your code that does the difference, and that is the result I would expect.


I didn't mean to insult Qt,
Don't worry, none of us is emotional (at least not in that way) about Qt.
Its not about being insulted, just about what is more feasible.

To the rest of what you wrote about the font size:

you can't set a font size unit as %. Point, ems and pixels will all take the same space regardless of the parent's size.
Not sure what you mean by that.
Font scalability is not something I am an expert of, by from what I know, using point size makes your text non scalable (which I guess is what is forcing you to "scale" it your self).
At any rate, the resolution is usually not something that changes, but is more a device property.
So I'd do the font sizing once when the application starts and not for every resize, since I don't think the resolution will change much from when you started the application - or does it in your case??
AND - I think with a bit more thought and research your problem can well be solved with "normal" methods, you are not the first person to fit text in a tight screen.
But, I could very well be wrong on that too.

wysota
15th September 2011, 12:16
Then a child widget of MainWindow of class Widget has resizeEvent() reimplemented:




void Widget::resizeEvent(QResizeEvent *event)
{
nameLabel->setFixedWidth(width()/4);
familyNameLabel->setFixedWidth(width()/4);

QWidget::resizeEvent(event);

}


Why don't you just use layouts? Then you can reimplement resizeEvent() and simply change the font size of your top-level widget. Since the font size is inherited by child widgets, they will adjust and since a layout manages them, their sizes will adjust. It seems to me you are trying to reach to your right ear with your left hand :)

pssss
15th September 2011, 17:20
My guess is that you have 3 objects of this class

I'm sure I only have one instance of this class.

It's a desktop app and I wanted the user to be able to resize it manually, that's what I meant by resolution. Also there are many different desktop resolutions the app could run on. However, if all else fails your comment has made me realize that allowing the user to resize is not essential, so I could just have different stylesheets and load them depending on screen resolution on startup and disable manual resizing.




Why don't you just use layouts? Then you can reimplement resizeEvent() and simply change the font size of your top-level widget. Since the font size is inherited by child widgets, they will adjust and since a layout manages them, their sizes will adjust. It seems to me you are trying to reach to your right ear with your left hand




I kind of tried this. The problem I had was that when resizeEvent() is called on the parentWidget, all the children have already had their sizes adjusted using their respective SizePolicies, when these new sizes for the children were calculated the layout system took into account the old font size, so they were given more space than they really deserved. Then when inside resizeEvent() I called my crappy function that calculates the biggest font size that fits inside a child, there will be more space than there should have been, so it won't be able to calculate the ideal new font size properly. Know what I mean? I've tried every combination of size policy, am I missing something?


Also, not all the children have the same font sizes. If I change the size on the parent, I don't think the proportion change will propagate to children which have had their own sizes set.


Thanks to you both.


EDIT: I think I did something wrong when trying ems a few days ago, I'll try again and get back to you.

pssss
15th September 2011, 18:05
Propagation is not working. I don't set font sizes in code, only on the parent widget, but the child which is of class QLabel is not getting it. Even if I manage to make propagation work, will I then be able to change that inherited size using ems in a stylesheet? Or using ems in a stylesheet would break the propagation?


EDIT: If I remove the stylesheet, font size propagation works, are stylesheets and font propagation not compatible? I made sure I don't change the property font-size anywhere, so I'm getting the impression that they are incompatible.


Thanks.

wysota
15th September 2011, 23:13
are stylesheets and font propagation not compatible?
They are probably not.

pssss
16th September 2011, 08:26
They are probably not.


Alright, I need the stylesheets. Is there a better way to do the font resizing than what I'm doing or to have proportional font sizes? Should I have a stylesheet for each resolution and block manual resizing?

Thanks.

wysota
16th September 2011, 09:26
To be honest, if I wanted to do a resolution-independent UI, I would rather use QML or QGraphicsView than widgets.

pssss
17th September 2011, 00:48
Ok, thanks.