PDA

View Full Version : QWidget resize troubles



ilariari
21st April 2015, 14:45
Hallo, I have to manage 3 different layout for each tab of a QTabWidget (but, in general, for its currentWidget).
MyClass::MyFunction is called every time a layout change is necessary.
In fact, my code is not able to let m_pWidget1 and m_pWidget2 be resized (both have resize() function overwritten, but it's not called as I expect).
Why?
And: How can I force m_pWidget1 and m_pWidget2 to be resized?

I post the code (initializations omitted, but it's not there the problem):




// .h

class MyClass
{
QTabWidget * m_pTabWidget;

QHBoxLayout * m_pHLayout;

QWidget * m_pWidget1;
QWidget * m_pWidget2;
};








// .cpp

void MyClass::MyFunction(void)
{
m_pHLayout = new QHBoxLayout();

m_pHLayout->setMargin(0);
m_pHLayout->setSpacing(0);

switch(m_eLayout)
{
case e_Layout_1:
{
m_pHLayout->addWidget(m_pWidget1);
m_pHLayout->addWidget(m_pWidget2);
}
break;
case e_Layout_2:
{
m_pHLayout->addWidget(m_pWidget1, 1);
m_pHLayout->addWidget(m_pWidget2, 2);
}
break;
case e_Layout_3:
{
m_pHLayout->addWidget(m_pWidget1, 2);
m_pHLayout->addWidget(m_pWidget2, 1);
}
break;
}

m_pTabWidget->currentWidget()->setLayout(m_pHLayout); //HERE - I expect that the resize event for both m_pWidget1 and pWidget2 is called.....
}

yeye_olive
21st April 2015, 17:59
From the documentation of QWidget::setLayout():

If there already is a layout manager installed on this widget, QWidget won't let you install another. You must first delete the existing layout manager (returned by layout()) before you can call setLayout() with the new layout.
No part of the code you posted deletes the existing layout, if any.

anda_skoa
21st April 2015, 20:14
Since the only thing you seem to change is the stretch factor associated with the two widgets, why don't you keep the layout and just call setStretchFactor()?

Cheers,
_

ilariari
22nd April 2015, 08:56
From the code I posted you are right, yeye_olive; in fact, all the object I reported as pointer (*) are in my original code SmartPointer, a class which incapsulate the pointer lifecycle avoiding memory leaks.
I worried it could be misleading to post the whole code, but I omitted an essential particular: the old layout is in fact destroyed, as the real code is:




SmartPointer<QHBoxLayout> m_pHLayout;

m_pHLayout = SmartPointer<QHBoxLayout>(new QHBoxLayout()); // operator = of class template <class T> class SmartPointer deletes the incapsulated object if it's assigned to a different one.



So, thank you for the hints, but the problem is not the old layout deletion (unless I have to call something like "detachLayout" before it goes deleted).
I'm suspecting that's not enough to simply assign a new layout to a certain widget (after having destroyed the previous one!) to grant the resizing of the layouts children.
I'm looking for the action I have to take to grant such resizing.

ilariari
22nd April 2015, 12:02
Hallo, i found a solution: no idea if it's stylish :) to call hide() and show() for currentWidget!!




void MyClass::MyFunction(void)
{
m_pTabWidget->currentWidget()->hide();

m_pHLayout = SmartPointer<QHBoxLayout>(new QHBoxLayout());

// ................. the same code as before .............................

m_pTabWidget->currentWidget()->setLayout(m_pHLayout); //HERE - I expect that the resize event for both m_pWidget1 and pWidget2 is called.....

m_pTabWidget->currentWidget()->show(); // ...in fact it's called HERE !!!!!!!!
}

anda_skoa
22nd April 2015, 13:42
So, why do you need a new layout if you are not changing the type of layout or ordering of widgets?

Cheers,
_

yeye_olive
22nd April 2015, 14:22
What you observe is strange. There are several ways to force a widget to update its layout like QLayout::activate() or QWidget::updateGeometry(), but they should not be needed.

Be careful with those smart pointers: I suppose that the widget deletes its layout in its destructor, which means that the last layout is deleted twice.

In any case, you should follow anda_skoa's suggestion and reuse the existing layout if you can.

ilariari
22nd April 2015, 14:32
To reuse the same layout is also feasible for me, i'll try to follow anda_skoa's suggestion..
Thank you!