PDA

View Full Version : Repositioning widgets in QGridLayout



Rayven
17th March 2011, 17:24
I am trying to create a dynamic (read: at runtime) layout for some custom plots, using a QGridLayout. On initialization, a single plot is displayed. The user selects to add other plots through menus, changing the overall layout. Adding the first object works fine, however adding the second object causes the first object to occupy/span both widgets with the second object in the correct position. Each subsequent object added is in the correct position, but the first object still spans the entire layout (can "see" the widget in the grid spacing/background).

void RawDataWindow::layoutPlots()
{
QWidget *ui_plotAreaWidget = qFindChild<QWidget*>( this, "plotAreaWidget" );
QGridLayout *plotLayout = (QGridLayout*) ui_plotAreaWidget->layout();

// Remove all plots from the layout to adjust spacing and setup reparenting
for( int p = 0; p < mPlots.count(); p++ )
{
plotLayout->removeWidget( mPlots.at( p ).plotObject );
mPlots.at( p ).plotObject->setParent( 0 );
}

if( mPlots.count() == 1 )
{
plotLayout->addWidget( mPlots.at( 0 ).plotObject );
}
else if( mPlots.count() == 2 )
{
// Create a 1x2 grid
plotLayout->addWidget( mPlots.at( 0 ).plotObject, 0, 0 );
plotLayout->addWidget( mPlots.at( 1 ).plotObject, 0, 1 );
}
else if( mPlots.count() == 3 )
{
// 2x2 grid with the top plot spanning across both columns
plotLayout->addWidget( mPlots.at( 0 ).plotObject, 0, 0, 1, 2 );
plotLayout->addWidget( mPlots.at( 1 ).plotObject, 1, 0 );
plotLayout->addWidget( mPlots.at( 2 ).plotObject, 1, 1 );
}
else if( mPlots.count() == 4 )
{
// 2x2 grid
plotLayout->addWidget( mPlots.at( 0 ).plotObject, 0, 0 );
plotLayout->addWidget( mPlots.at( 1 ).plotObject, 0, 1 );
plotLayout->addWidget( mPlots.at( 2 ).plotObject, 1, 0 );
plotLayout->addWidget( mPlots.at( 3 ).plotObject, 1, 1 );
}
}


I believe this is causing further issues in that whichever object I add last does not recieve mousePress/Release/Move events, but this is just speculation until I resolve the layout issue.

Any ideas?

Windows 7
VS 2008
Qt 4.6.3

Santosh Reddy
17th March 2011, 18:06
Do you mean that the subsequent widgetadded are overlapping with first widget?

Rayven
17th March 2011, 18:10
Do you mean that the subsequent widgetadded are overlapping with first widget?

Yes, but only overlapping the very first widget added. The positions of widgets 2 - 4 are in the correct positions.

Santosh Reddy
17th March 2011, 18:43
try specifying the row and col span as 1 for the first and all the widgets, it worked for me.

Rayven
17th March 2011, 19:15
Did not change anything. However, if I take out the line


mPlots.at( p ).plotObject->setParent( 0 );

the very first plot draws behind the second plot. Once I add the third plot, however the layout "fixes" itself. If I remove all plot (toggle them off) and re-show two plots, the exact same issue occurs.

So now the code looks like this:


void RawDataWindow::layoutPlots()
{
QWidget *ui_plotAreaWidget = qFindChild<QWidget*>( this, "plotAreaWidget" );
QGridLayout *plotLayout = (QGridLayout*) ui_plotAreaWidget->layout();

// Remove all plots from the layout to adjust spacing and setup reparenting
for( int p = 0; p < mPlots.count(); p++ )
{
plotLayout->removeWidget( mPlots.at( p ).plotObject );

// Note this line was "causing" the first plot to ALWAYS draw behind the others
// Removing this "fixes" the layout AFTER adding a third plot object
//mPlots.at( p ).plotObject->setParent( 0 );
}

if( mPlots.count() == 1 )
{
plotLayout->addWidget( mPlots.at( 0 ).plotObject, 0, 0, 1, 1 );
}
else if( mPlots.count() == 2 )
{
// Create a 1x2 grid
plotLayout->addWidget( mPlots.at( 0 ).plotObject, 0, 0, 1, 1 );
plotLayout->addWidget( mPlots.at( 1 ).plotObject, 0, 1, 1, 1 );
}
else if( mPlots.count() == 3 )
{
// 2x2 grid with the top plot spanning across both columns
plotLayout->addWidget( mPlots.at( 0 ).plotObject, 0, 0, 1, 2 );
plotLayout->addWidget( mPlots.at( 1 ).plotObject, 1, 0, 1, 1 );
plotLayout->addWidget( mPlots.at( 2 ).plotObject, 1, 1, 1, 1 );
}
else if( mPlots.count() == 4 )
{
// 2x2 grid
plotLayout->addWidget( mPlots.at( 0 ).plotObject, 0, 0, 1, 1 );
plotLayout->addWidget( mPlots.at( 1 ).plotObject, 0, 1, 1, 1 );
plotLayout->addWidget( mPlots.at( 2 ).plotObject, 1, 0, 1, 1 );
plotLayout->addWidget( mPlots.at( 3 ).plotObject, 1, 1, 1, 1 );
}
}

Santosh Reddy
17th March 2011, 19:22
You need not reparent the widget, while repositioning the widget in the same layout, the layout manager will take care of it, also check the example project attached. I tried with QPushButton, you may replace with the plot.

try removing "plotLayout->removeWidget( mPlots.at( p ).plotObject );" this may also be not required.

Rayven
17th March 2011, 20:01
You need not reparent the widget, while repositioning the widget in the same layout, the layout manager will take care of it, also check the example project attached. I tried with QPushButton, you may replace with the plot.

try removing "plotLayout->removeWidget( mPlots.at( p ).plotObject );" this may also be not required.

The removeWidget was not needed, but the same issue occurs.

Added after 15 minutes:


The removeWidget was not needed, but the same issue occurs.
Also, could not open your example code. ZIP was corrupted.

Santosh Reddy
18th March 2011, 17:57
Rename this to .zip 6104

Rayven
21st March 2011, 14:30
Well, after much head scratching I (with the help of a colleague) was able to figure out that it had nothing to do with the creation of the layout, but rather with the creation of the plotObject, specifically the passing of the parent object. I was not passing ui_plotAreaWidget as the parent when creating the object, thinking that plotLayout->addWidget(...) reparented the object, which is not the case. Setting the plotObject parent as ui_plotAreaWidget fixed all the issues!

Thank for all your assistance!