PDA

View Full Version : [QWidget] How to save proporties?



Macok
28th March 2009, 22:23
How can I save proporties of QWidget while resizing?
For example I want QWidget's height to be always 3/4 of width.
Thanks in advance!

Lykurg
28th March 2009, 22:36
I don't an easy option for that, but you can reimpl QWidget::resizeEvent ( QResizeEvent * event ) and fix the proportion yourself.

Macok
28th March 2009, 22:45
Can you give me an example?
I tried something like this:
MyWidget::resizeEvent(QResizeEvent *e){
e->size()->setWidth(...);
e->size()->setHeight(...);
QWidget::resizeEvent(e);
}But as I remember there wasn't even any difference...

wysota
28th March 2009, 23:49
There is also QWidget::heightForWidth().

Macok
29th March 2009, 00:33
Thanks, but how should I reimplement that QWidget::heightForWidth()?
I tried this:
int QWidget::heightForWidth(int w) const{
return w*3/(double)4;
}What's wrong?

wysota
29th March 2009, 09:54
That's not enough. You also have to tell the layout (through size policy) that you want to use heightForWidth. I'm also not sure if you can actually set it on a top level widget (you might have to set it on a child). Also remember this controlls the preferred width/height dependency. If you want to force it, you have to set a size constraint on the widget's layout. So if you don't know how to do that, reimplementing resizeEvent() might be a better (or at least faster to implement) idea. Your current implementation didn't work because QResizeEvent::size() returns a copy of the size object and after you modify the copy you need to set it back on the widget. It will work if you implement it properly.

Macok
29th March 2009, 11:25
Your current implementation didn't work because QResizeEvent::size() returns a copy of the size object and after you modify the copy you need to set it back on the widget. It will work if you implement it properly.Thanks, but how can I do it?
Should I use setFixedPosition() in resizeEvent()?

wysota
29th March 2009, 13:29
No, you should use resize() or setGeometry() for example...

Macok
29th March 2009, 13:40
I tried, but it still doesn't work.
Here's the code for 1:1 proporties:
void GLWidget::resizeEvent(QResizeEvent *e){
QResizeEvent *event;
if(e->size().width()<e->size().height()){
event=new QResizeEvent(QSize(e->size().height(), e->size().height()), e->oldSize());
resize(e->size().height(), e->size().height());
}
else{
event=new QResizeEvent(QSize(e->size().width(), e->size().width()), e->oldSize());
resize(e->size().width(), e->size().width());
}
QGLWidget::resizeEvent(event);
}
If width is bigger than height, i set height to be the same as width and vice versa.
What's wrong?

wysota
29th March 2009, 13:55
Why are you creating a new resize event? :confused:

Please, if you use some method (like resizeEvent) please read its docs first. It's clearly stated the event is delivered after the widget has already been resized so changing the data sent to the base implementation won't do you any good especially that QWidget's resizeEvent() is empty.


void ...::resizeEvent(QResizeEvent *re){
if(re->width()==re->height()) return; // avoid infinite loop
int larger = qMax(re->width(), re->height());
resize(larger, larger);
}

Macok
29th March 2009, 14:22
Thanks, now it's ok.

Why are you creating a new resize event?If I don't callQGLWidget::resizeEvent(...) QGLWidget will not scale the scene displayed in it.


Finally, this works fine:
void GLWidget::resizeEvent(QResizeEvent *re){
if(re->size().width()==re->size().height()) return; // avoid infinite loop
int min = qMin(re->size().width(), re->size().height());
resize(larger, larger);

QGLWidget::resizeEvent(new QResizeEvent(QSize(min, min), re->oldSize()));
}
But I have one more question.
When width of my window is bigger than height, widget will not be expanded on the whole window, but it'll be placed on the left side.
I'd like to place widget exactly in the middle of window's width.

Is there any simple way to reach this effect?
Maybe something with setGeometry()?
Thanks in advance.

wysota
29th March 2009, 14:29
You have a memory leak. As for the question, you already answered it.

Macok
29th March 2009, 14:43
No, I didn't.
Maybe you misunderstood my question.
I have widget with proporties 1:1, but window when this widget is placed has another proporties, so widget is placed on the left side, or top of the window.
I'd like to place it in the middle, but I don't know how to do it.
I tried to use spacers but without results.

talk2amulya
29th March 2009, 15:09
setGeometry() or move()...to desired location..shouldnt be hard

wysota
29th March 2009, 15:26
No, I didn't.
Maybe you misunderstood my question.
Maybe I have.


I have widget with proporties 1:1, but window when this widget is placed has another proporties, so widget is placed on the left side, or top of the window.
So your GL widget is not a top-level window, right? In that case you should have used heightForWidth...


I'd like to place it in the middle, but I don't know how to do it.
I tried to use spacers but without results.

Anyway... you don't need spacers although of course you can use them. When you place your widget in a layout, make it a grid layout and when calling addWidget() you can pass an alignment flag. But if you are using Designer to design your window then spacers are an easier way of obtaining the result. Just remember you'll have to decide which direction you want "anchored" to the window - you can't use four spacers or else your GL widget won't resize at all, you have to place two spacers either on the left and right of the widget or above and below it.

On second thought you might get away with four spacers but you need to set the size policy of your GL widget to Expanding in both directions. If you can accept that then it should work (provided it won't break your aspect ratio).