PDA

View Full Version : resizing widgets depending on a main widget size



luf
16th June 2009, 12:21
I'm trying to make a custom widget get it's size (fixed size) set depending on the size of a stacked widget.

I pick up the resize in resizeEvent of the main widget, and emit a signal to tell the other widget to resize. The problem is that when the custom widget has large fixed size, and I try to make the window smaller, it doesn't allow to scale/resize down properly. It works if I scale down several times, but that isn't a good solution.

I've figured out that I really should set the size before the resizeevent, as when that is called, the layout is already done. I just don't figure out what event it should be done in.

I tried implementing the following, as an small example.

custom.h:


class QCustomMainPage : QWidget
{
public:
QCustomMainPage(QWidget *parent)
protected:
void resizeEvent ( QResizeEvent *re );
signals:
void sizeChange(QSize size);
};

class QCustomResizeWidget : QFrame
{
public:
QCustomResizeWidget (QWidget *parent)
public slots:
void sizeChangeSlot(QSize size);
protected:
QSize sizeHint(void) const;
QSize minimumSizeHint(void) const;
QSize currentsize;
};


custom.cpp


QCustomResizeWidget::QCustomResizeWidget(QWidget *parent):QFrame (parent){
QLabel *label1 = new QLabel("label1");
QLabel *label2 = new QLabel("label2");
QVBoxLayout *clayout = new QVBoxLayout(this);
clayout->addWidget(label1);
clayout->addWidget(label2);
}

void QCustomResizeWidgetsize::ChangeSlot(QSize size){
currentsize = QSize(size.width()/10, size.width()/10); // keep it square
this->setFixedSize(currentsize);
}
QSize QCustomResizeWidgetsize::sizeHint(void) const{
return this->currentsize;
}
QSize minimumSizeHint(void) const{
// return this->currentsize;
return QSize(1,1); // allow widget to resize down to 1,1 (to get this partially working)
}

QCustomMainPage::QCustomMainPage(QWidget *parent) : QWidget(parent){
QCustomResizeWidget *customwidget1 = new QCustomResizeWidget;
connect(this, SIGNAL(sizeChange(QSize)), customwidget1, SLOT(ChangeSlot(QSize)));
QCustomResizeWidget *customwidget2 = new QCustomResizeWidget;
connect(this, SIGNAL(sizeChange(QSize)), customwidget1, SLOT(ChangeSlot(QSize)));
QCustomResizeWidget *customwidget3 = new QCustomResizeWidget;
connect(this, SIGNAL(sizeChange(QSize)), customwidget1, SLOT(ChangeSlot(QSize)));
QCustomResizeWidget *customwidget4 = new QCustomResizeWidget;
connect(this, SIGNAL(sizeChange(QSize)), customwidget1, SLOT(ChangeSlot(QSize)));

QGridLayout *grid = new QGridLayout(this);
grid->addWidget(customwidget1, 0,0);
grid->addWidget(customwidget1, 0,1);
grid->addWidget(customwidget1, 1,0);
grid->addWidget(customwidget1, 1,1);
}

QCustomMainPage::resizeEvent(QResizeEvent *re ){
emit sizeChange(re->size());
}

wysota
16th June 2009, 12:34
Hmm... could you show an example of how would you use such widgets?

luf
16th June 2009, 12:42
It's to keep a widget the same size throughout an application depending on the main window size.

The widget might contain anything (Pixmap, text, other widgets, but should always be the same size).

wysota
16th June 2009, 13:15
But you don't need any special treatment to achieve that... Just set the size policies right.

luf
16th June 2009, 14:00
I got really carried away into the sizehints, custom x,y,z and didn't see the obvious...

I forgot to add stretch in some of the layouts to the widgets, meaning that the layout would use the minimum possible size.

Thanks wysota!

For others experiencing similar issues:
setMaximiumSize on the widget + QSizePolicy::MinimumExpanding should make sure the widget is the correct size, and is possible to shrink.
make sure all widgets have stretch added to them in layouts, so they get the size you expect them to have.

This should work:



class QCustomMainPage : QWidget
{
public:
QCustomMainPage(QWidget *parent)
protected:
void resizeEvent ( QResizeEvent *re );
signals:
void sizeChange(QSize size);
};

class QCustomResizeWidget : QFrame
{
public:
QCustomResizeWidget (QWidget *parent)
public slots:
void sizeChangeSlot(QSize size);
};




QCustomResizeWidget::QCustomResizeWidget(QWidget *parent):QFrame (parent){
QLabel *label1 = new QLabel("label1");
QLabel *label2 = new QLabel("label2");
QVBoxLayout *clayout = new QVBoxLayout(this);
clayout->addWidget(label1);
clayout->addWidget(label2);
}

void QCustomResizeWidgetsize::ChangeSlot(QSize size){
this->setFixedSize(QSize(size.width()/10, size.height()/10));
}

QCustomMainPage::QCustomMainPage(QWidget *parent) : QWidget(parent){
QCustomResizeWidget *customwidget1 = new QCustomResizeWidget;
connect(this, SIGNAL(sizeChange(QSize)), customwidget1, SLOT(ChangeSlot(QSize)));
QCustomResizeWidget *customwidget2 = new QCustomResizeWidget;
connect(this, SIGNAL(sizeChange(QSize)), customwidget2, SLOT(ChangeSlot(QSize)));
QCustomResizeWidget *customwidget3 = new QCustomResizeWidget;
connect(this, SIGNAL(sizeChange(QSize)), customwidget3, SLOT(ChangeSlot(QSize)));
QCustomResizeWidget *customwidget4 = new QCustomResizeWidget;
connect(this, SIGNAL(sizeChange(QSize)), customwidget4, SLOT(ChangeSlot(QSize)));
QCustomResizeWidget *customwidget5 = new QCustomResizeWidget;
connect(this, SIGNAL(sizeChange(QSize)), customwidget5, SLOT(ChangeSlot(QSize)));
QCustomResizeWidget *customwidget6 = new QCustomResizeWidget;
connect(this, SIGNAL(sizeChange(QSize)), customwidget6, SLOT(ChangeSlot(QSize)));

QHBoxLayout *hbox = new QHBoxLayout();
hboxlayout->addStretch(1); // push widgets to the right
hbox->addWidget(customwidget5, 1) // remember stretch
hbox->addWidget(customwidget6, 1) // remember stretch
QGridLayout *grid = new QGridLayout();
grid->addWidget(customwidget1, 0,0);
grid->addWidget(customwidget2, 0,1);
grid->addWidget(customwidget3, 1,0);
grid->addWidget(customwidget4, 1,1);
QVBoxLayout *mainlayout = QVBoxLayout(this);
mainlayout->addLayout(hbox);
mainlayout->addLayout(grid);
}

QCustomMainPage::resizeEvent(QResizeEvent *re ){
emit sizeChange(re->size());
}


(to improve speed of application, the calculation of widget size should be done before emitting the sizeChange signal).

kyue
9th October 2009, 22:00
I have a similar problem. Is there a way to find the size of QCustomResizeWidget? Perhaps, I should describe my situation first.

I have an application similar to Windows Explorer. In particular, when a User can view icons/images as "Thumbnails". The difference in my application, is the thumbnail images are not a fixed size. The thumbnail size is determined by calculations that require the width of the parent widget (ie. the Main Window).

I was able to get the correct size in certain situations. I tried using any function that returned QSize or QRect and all of them returned a funny number. :confused: It looks like the dimensions get changed when I add a layout to my Main Window (I use a GridLayout). After reading a bit of the Qt documentation, adding a layout instantly shrinks the size of the Main Window.

After reading this thread, I tried playing with the Size Policies and I was still unable to get the value I was looking for. Is there something else I should be doing, or am I choosing the wrong flags? I've tried all the flags, and I'm still not getting the correct dimensions.

Any help will be greatly appreciated. :)

Peppy
10th October 2009, 17:13
Just use:

QWidget::resize(rect().width(),100);