Layout scratching head...
-
@SPlatten said in Layout scratching head...:
If you take at look at the XML in my post, thats exactly what is done:
Your QGroupBox shouldn't be part of this layout and the layout should not be the QGroupBox's parent. The QGroupBox's parent will automatically become whatever layout it is added to.
-
@SPlatten said in Layout scratching head...:
If you take at look at the XML in my post, thats exactly what is done:
Your QGroupBox shouldn't be part of this layout and the layout should not be the QGroupBox's parent. The QGroupBox's parent will automatically become whatever layout it is added to.
-
@SPlatten said in Layout scratching head...:
QLayout* pobjLayout(pobjParent->layout());
How are you getting the layout for the buttons now? It should be a new layout, so I don't think you can obtain it with this line.
-
@SPlatten said in Layout scratching head...:
the first item added to the layout is the group box
Do not do this step.
@mchinand , in my sample code that works:
QHBoxLayout* phbxLayout(new QHBoxLayout); QGroupBox* pobjGroup(new QGroupBox); pobjGroup->setLayout(phbxLayout); for( int i=1; i<=3; i++ ) { QPushButton* pbtnTemp(new QPushButton(QString("Button %1").arg(i))); phbxLayout->addWidget(pbtnTemp); } pvbxLayout->addWidget(pobjGroup);
In the code that doesn't work:
QWidget* pobjWidget(mpobjWidget); if ( pobjWidget != nullptr ) { QLayout* pobjLayout(pobjWidget->layout()); if ( pobjLayout == nullptr && mpobjParent != nullptr ) { //Does the parent have a layout? if ( mpobjParent->mpobjWidget != nullptr ) { pobjLayout = mpobjParent->mpobjWidget->layout(); } } if ( pobjLayout != nullptr ) { QFormLayout* pfrmlo(qobject_cast<QFormLayout*>(pobjLayout)); QGridLayout* pgrdlo(qobject_cast<QGridLayout*>(pobjLayout)); QHBoxLayout* phbxlo(qobject_cast<QHBoxLayout*>(pobjLayout)); QVBoxLayout* pvbxlo(qobject_cast<QVBoxLayout*>(pobjLayout)); if ( pfrmlo != nullptr ) { pobjGroupBox->setLayout(pfrmlo); pfrmlo->addWidget(pobjWidget); } else if ( pgrdlo != nullptr ) { //pgrdlo->addItem() } else if ( phbxlo != nullptr ) { pobjGroupBox->setLayout(phbxlo); phbxlo->addWidget(pobjWidget); } else if ( pvbxlo != nullptr ) { pobjGroupBox->setLayout(pvbxlo); pvbxlo->addWidget(pobjWidget); } } }
The only difference is that this code isn't a loop but part of a function thats called for each button.
-
@SPlatten said in Layout scratching head...:
QHBoxLayout* phbxLayout(new QHBoxLayout); QGroupBox* pobjGroup(new QGroupBox); pobjGroup->setLayout(phbxLayout); for( int i=1; i<=3; i++ ) { QPushButton* pbtnTemp(new QPushButton(QString("Button %1").arg(i))); phbxLayout->addWidget(pbtnTemp); } pvbxLayout->addWidget(pobjGroup);
In this code, you are not adding the QGroupBox to the same layout as the layout you are adding the buttons to. From what you said above and in the code below, I think you are adding the QGroupBox and buttons to the same layout.
-
@SPlatten said in Layout scratching head...:
QHBoxLayout* phbxLayout(new QHBoxLayout); QGroupBox* pobjGroup(new QGroupBox); pobjGroup->setLayout(phbxLayout); for( int i=1; i<=3; i++ ) { QPushButton* pbtnTemp(new QPushButton(QString("Button %1").arg(i))); phbxLayout->addWidget(pbtnTemp); } pvbxLayout->addWidget(pobjGroup);
In this code, you are not adding the QGroupBox to the same layout as the layout you are adding the buttons to. From what you said above and in the code below, I think you are adding the QGroupBox and buttons to the same layout.
-
@mchinand , the sample code I posted created a new layout then uses that layout in the group box, then adds widgets to the layout and finally adds the group to different vertical layout.
@SPlatten said in Layout scratching head...:
@mchinand , the sample code I posted created a new layout then uses that layout in the group box, then adds widgets to the layout and finally adds the group to different vertical layout.
Right, your sample code is correct, but it seems your actual code is adding the qgroupbox and buttons to the same layout.
-
@SPlatten said in Layout scratching head...:
@mchinand , the sample code I posted created a new layout then uses that layout in the group box, then adds widgets to the layout and finally adds the group to different vertical layout.
Right, your sample code is correct, but it seems your actual code is adding the qgroupbox and buttons to the same layout.
@mchinand, another rewrite:
QWidget* pobjWidget(mpobjWidget); if ( pobjWidget != nullptr ) { QLayout* pobjLayout(pobjWidget->layout()); if ( pobjLayout == nullptr && mpobjParent != nullptr ) { //Does the parent have a layout? if ( mpobjParent->mpobjWidget != nullptr ) { pobjLayout = mpobjParent->mpobjWidget->layout(); } } if ( pobjLayout != nullptr ) { pobjLayout->addWidget(pobjWidget); pobjGroupBox->setLayout(pobjLayout); } }
Result still the same...
-
@SPlatten said in Layout scratching head...:
if ( pobjLayout != nullptr ) { pobjLayout->addWidget(pobjWidget); pobjGroupBox->setLayout(pobjLayout); } }
Is the QGroupBox ever
pobjWidget
for this code? You know from your sample code how the widgets (the QGroupbox and buttons) should be added to the layouts, you just need to replicate that in your code. -
I don't know much about your XML generation, but what if it was like this instead? This better reflects what the code should be.
<groupbox id="btnbar"> <layout type="horizontal" width="128"> <button id="btnApply" group="btnbar" api="applyChanges"> <subscriber signal="clicked" target="simon2.js@applyButton"/> </button> <button id="btnUndo" group="btnbar" api="undoChanges"/> <button id="btnOK" group="btnbar" api="submitAndClose"/> </layout> </groupbox>
-
I don't know much about your XML generation, but what if it was like this instead? This better reflects what the code should be.
<groupbox id="btnbar"> <layout type="horizontal" width="128"> <button id="btnApply" group="btnbar" api="applyChanges"> <subscriber signal="clicked" target="simon2.js@applyButton"/> </button> <button id="btnUndo" group="btnbar" api="undoChanges"/> <button id="btnOK" group="btnbar" api="submitAndClose"/> </layout> </groupbox>
@mchinand , this might look a bit over the top, I have a class clsQtLayout which is derived from QWidget, the reason for this is because the class supports layouts with a scrollable area which can only be accommodated by using a widget to contain everything.
After much work the QVBoxLayout works great, I have a form layout inside that can have a fixed height and in my example contains radio buttons, it can be scrollable within the vertical layout.
I have tried the same techniques for the QHBoxLayout and this is where I'm having problems, for some reason which I'm not seeing it just doesn't work. Going back to my XML:
<layout type="form" height="72" hspacing="0"> <buttongroup id="enSEX" dbfield="vcSex"/> <radiobutton id="rdoM" group="enSEX" text="Male" default="true" position="0,0"/> <radiobutton id="rdoF" group="enSEX" text="Female" position="1,0"/> </layout>
This XML behind the scenes creates a QVBoxLayout because the height of the required QFormLayout has a fixed height. A QWidget is created which the QScrollArea connected to. The QScrollArea is then connected to the QVBoxLayout.
if ( intFixedHeight > 0 ) { //Create a vertical layout as the container for this layout pobjVBox = new QVBoxLayout; //Create and set-up scroll area mpobjScroller = new QScrollArea; mpobjScroller->setWidget(pobjContainer); mpobjScroller->setFixedHeight(intFixedHeight); pobjVBox->addWidget(mpobjScroller); } pobjLayout = new QFormLayout; //Set-up form pobjLayout->setContentsMargins(0,0,0,0); pobjLayout->setSpacing(0); QString strHorzSpacing(mpobjNode->strGetAttribute( clsXMLnode::mscszAttrSpacingH)); if ( strHorzSpacing.isEmpty() != true ) { ((QFormLayout*)pobjLayout)->setHorizontalSpacing(strHorzSpacing.toInt()); } if ( pobjContainer != nullptr ) { pobjContainer->setLayout(pobjLayout); }
This all works fine, the following XML is for the horizontal layout:
<layout id="btnbarLO" type="horizontal" width="128"> <groupbox id="btnbar" layout="btnbarLO" properties="background-color:#ff0000;"/> <button id="btnApply" group="btnbar" api="applyChanges"> <subscriber signal="clicked" target="simon2.js@applyButton"/> </button> <button id="btnUndo" group="btnbar" api="undoChanges"/> <button id="btnOK" group="btnbar" api="submitAndClose"/> </layout>
And the code in the layout class for this, which should be very similar to the vertical layout:
if ( intFixedWidth > 0 ) { //Create a vertical layout as the container for this layout pobjHBox = new QHBoxLayout; //Create and set-up scroll area mpobjScroller = new QScrollArea; mpobjScroller->setWidget(pobjContainer); mpobjScroller->setFixedWidth(intFixedWidth); pobjHBox->addWidget(mpobjScroller); } pobjLayout = new QHBoxLayout; //Set-up form pobjLayout->setContentsMargins(0,0,0,0); pobjLayout->setSpacing(0); QString strHorzSpacing(mpobjNode->strGetAttribute( clsXMLnode::mscszAttrSpacingH)); if ( strHorzSpacing.isEmpty() != true ) { ((QHBoxLayout*)pobjLayout)->addSpacing(strHorzSpacing.toInt()); } if ( pobjContainer != nullptr ) { pobjContainer->setLayout(pobjLayout); }
However this isn't working and the results are as shown in the original screenshot:
I've set the background colour of the QGroupBox to red to clarify where it is.
[edit] I can see it isn't clear, so elsewhere in my node handling code there is this logic where nodes are appended to parent nodes:
QWidget* pobjWChild(pobjChild->pobjGetWidget()); if ( pobjWChild != nullptr && mstrName.compare(clsXMLnode::mscszNodeLayout) == 0 ) { //Yes, does the parent have a layout? QLayout* pobjLayout(pobjGetLayout()); if ( pobjLayout != nullptr ) { QString strType(strGetAttribute(clsXMLnode::mscszAttrType)); QFormLayout* pobjForm(qobject_cast<QFormLayout*>(pobjLayout)); //Add the widget for the layout if ( pobjForm != nullptr && strType.compare(clsXMLnode::mscszLayoutVertical) == 0 ) { pobjForm->addRow(pobjWChild); } else { pobjLayout->addWidget(pobjWChild); } } }