Layout scratching head...
-
I am developing an XML engine that will enable anyone to design a GUI in XML with JavaScript to supplement the design.
The XML form:
<?xml version="1.0" encoding="utf-8"?> <form title="Test form" id="frmTest" hspacing="0" vspacing="0" width="480" height="480" modal="false"> <entry control="listwidget" label="Select:" id="enSEL" cols="24" rows="1" mode="single" excludeFromChangeCheck="true" resetPropertiesOnChange="true" eol="true"> <subscriber signal="itemSelectionChanged" target="simon2.js@listWidgetHandler"/> <subscriber signal="currentItemChanged" target="simon2.js@listWidgetChanged"/> </entry> <entry control="lineedit" label="First name:" id="enFN" eol="true" cols="24" maxlength="24" accept="alpha_only" dbfield="vcFirstName"/> <entry control="lineedit" label="Surnname:" id="enSN" eol="true" cols="24" maxlength="24" accept="alpha_only" dbfield="vcSurName"/> <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> <entry control="textedit" label="Address:" id="enADR" eol="true" maxlength="256" accept="alpha_numeric" cols="24" rows="5" dbfield="vcAddress"/> <entry control="checkbox" label="Employed:" id="enEmp" eol="true" dbfield="intEmployed" textpos="left"/> <layout type="horizontal" width="128"> <groupbox id="btnbar"/> <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> <on saveChanges="Save changes before changing selection?"/> <on setup="simon2.js@setupForm"/> </form>
This is just a demo. The vertical layout of the radio buttons works great. However the horizontal layout doesn't work:
The 3 push buttons appear outside of the QGroupBox, I've looked at the code in the debugger, this screenshot is after adding a widget to the horizontal layout:
I am struggling to see why it doesn't work, the push button widget btnApply has the horizontal layout as the parent. The group box has the horizontal layout as its parent:
My code:if ( pobjGroupBox != nullptr ) { QWidget* pobjWidget(pobjGetWidget()); if ( pobjParent != nullptr && pobjWidget != nullptr ) { //Does the parent have a layout? QLayout* pobjLayout(pobjParent->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 ) { pfrmlo->addWidget(pobjWidget); } else if ( pgrdlo != nullptr ) { //pgrdlo->addItem() } else if ( phbxlo != nullptr ) { phbxlo->addWidget(pobjWidget); } else if ( pvbxlo != nullptr ) { pvbxlo->addWidget(pobjWidget); } pobjGroupBox->setLayout(pobjLayout); } } }
[edit], in a prototyping application I wrote, I've just added:
QHBoxLayout* phbxLayout(new QHBoxLayout); QGroupBox* pobjGroup(new QGroupBox); for( int i=1; i<=3; i++ ) { QPushButton* pbtnTemp(new QPushButton(QString("Button %1").arg(i))); phbxLayout->addWidget(pbtnTemp); } pobjGroup->setLayout(phbxLayout); pvbxLayout->addWidget(pobjGroup);
And this works perfectly, comparing the logic now for any differences. Can anyone help?
-
@SPlatten said in Layout scratching head...:
The group box has the horizontal layout as its parent:
This part doesn't sound correct. The horizontal layout you add the buttons to shouldn't be the parent of the QGroupBox. Here's the QGroupBox example code. There should be a separate layout for widgets within the QGroupBox.
-
@SPlatten said in Layout scratching head...:
The group box has the horizontal layout as its parent:
This part doesn't sound correct. The horizontal layout you add the buttons to shouldn't be the parent of the QGroupBox. Here's the QGroupBox example code. There should be a separate layout for widgets within the QGroupBox.
@mchinand , did you see the [edit] section at the end of my post? that works but I can't see whats different about what I am doing.
In the code that works I set the layout for the group then add the group the the vertical layout.
In the code that doesn't work, same, I set the layout for the group and is a child of the layout.
I'm looking closer at the code that works and in this, none of the widgets have parent nodes, could this explain why it works and the code that doesn't work, all nodes have parents?
-
I think it might just look like it's working because the QGroupBox is added to a QVBoxLayout which is the same type of layout the buttons are added to (when it 'works'). Is your QGroupBox visible in your screenshot? For testing purposes, can you set the title to your QGroupBox?
-
I think it might just look like it's working because the QGroupBox is added to a QVBoxLayout which is the same type of layout the buttons are added to (when it 'works'). Is your QGroupBox visible in your screenshot? For testing purposes, can you set the title to your QGroupBox?
-
@mchinand , yes, thats the small grey box above the buttons, I think because I it has no content, its too small to show a Title, I just tried and the title isn't displayed.
-
@mchinand said in Layout scratching head...:
You need to create a new layout for the items you want in your QGroupBox.
If you take at look at the XML in my post, thats exactly what is done:
<layout type="horizontal" width="128"> <groupbox id="btnbar"/> <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>
-
@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>