PDA

View Full Version : Dynamically resize spacing



trskel
27th September 2007, 17:15
I have a QHBoxLayout that contains a fixed size spacer, a widget and another fixed size spacer. I connected the resizing signal of another widget to a slot where I would like to update the width of the first spacer, but I cannot find a way to do it. How can I update the width of a spacer that is already in the layout?

I tried creating my own QSpacerItems andd add them to the layout using addItem(), so later on I can call their changeSize(), but it does not have any effect.

Any ideas?

Thanks

marcel
27th September 2007, 18:19
From Assistant:


Note that if changeSize() is called after the spacer item has been added to a layout, it is necessary to invalidate the layout in order for the spacer item's new size to take effect.

trskel
28th September 2007, 09:50
I think it is a refresh problem. The spacers do not resize when I call changeSize, but if then I change the main window size or the size of the splitter where my widgets are, it instantly updates and the spacers are resized.
I tried calling repaint() and even updateGeometry() after the call to changeSize(), but it doesn't make a difference. How can I force this update? What does the resizeEvent do that repaint() and updateGeometry() don't?

jpn
28th September 2007, 09:59
Try calling invalidate() (http://doc.trolltech.com/4.3/qlayoutitem.html#invalidate) on the layout.

widget->layout()->invalidate();

trskel
28th September 2007, 10:43
Thanks, tried that but still does not work :eek:
Need a way to trigger an update similar to the one that is done during resizeEvent()

jpn
28th September 2007, 11:14
I gave it a quick try and it seems to work at least for a top level widget:


#include <QtGui>

class Window : public QWidget
{
Q_OBJECT
public:
Window()
{
int spacing = 20;

QSpinBox* spinbox = new QSpinBox(this);
spinbox->setStyleSheet("background: red");
spinbox->setValue(spacing);

QLabel* label = new QLabel(this);
label->setStyleSheet("background: blue");
label->setNum(spacing);

QVBoxLayout* layout = new QVBoxLayout(this);
spacer = new QSpacerItem(spacing, spacing);
layout->addWidget(spinbox);
layout->addItem(spacer);
layout->addWidget(label);

connect(spinbox, SIGNAL(valueChanged(int)), label, SLOT(setNum(int)));
connect(spinbox, SIGNAL(valueChanged(int)), this, SLOT(setSpacing(int)));
}

private slots:
void setSpacing(int spacing)
{
spacer->changeSize(spacing, spacing);
layout()->invalidate();
}

private:
QSpacerItem* spacer;
};

int main(int argc, char* argv[])
{
QApplication a(argc, argv);
Window w;
w.show();
return a.exec();
}

#include "main.moc"

I suppose the spacing is not homogeneous over the layout? Otherwise you could simply use QBoxLayout::setSpacing().

trskel
28th September 2007, 11:52
It is a quite complex layout setup, with nested layouts (I'm sorry but I cannot post the code). There is a Q3ListView bellow and I want to set the spacer width to match that of one column of the list view. I think the resizing is done internally, but it never gets refreshed to the GUI. If I manually resize the window in the GUI, then magically everything gets to it's required size.

I finally solved it by calling hide() and then show(), forcing a full refresh. Not a very elegant solution but it works.