Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QGridLayout, help...



  • The following is a demo produced by my engine:
    Screenshot 2021-12-01 at 20.29.17.png
    The XML for this:

    <?xml version="1.0" encoding="utf-8"?>
    <form title="Test form" id="frmTest" hspacing="0" vspacing="0" width="420"
    	  height="360" 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="Surname" id="enSN" eol="true"
    		   cols="24" maxlength="24" accept="alpha_only" dbfield="vcSurName"/>
    	<label text="Sex"/>		   
    	<layout id="rdoLO" height="56" hspacing="0" scrollbar="false" 
    			eol="true" type="grid"
     			vspacing="0" properties="QLayout {background-color:#ffaaaa;}">
    		<buttongroup id="enSEX">
    			<radiobutton id="rdoM" height="28" text="Male" default="true"/>
    			<radiobutton id="rdoF" height="28" text="Female"/>
    		</buttongroup>
    	</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"/>
    	<layout id="btnbarLO"  scrollbar="false" type="horizontal" colspan="2">
    		<buttongroup id="enBar">
    			<button id="btnApply" api="applyChanges">
    				<subscriber signal="clicked" target="simon2.js@applyButton"/>
    			</button>
    			<button id="btnUndo" api="undoChanges"/>
    			<button id="btnOK" api="submitAndClose"/>	
    		</buttongroup>
    	</layout>
    	<on saveChanges="Save changes before changing selection?"/>
    	<on setup="simon2.js@setupForm"/>
    </form>
    

    Its still very much a work in progress, the code that takes the XML and turns it into a layout:

    void clsScriptHelper::addNodesToGUI(clsXMLnode* pobjParent
                                       ,QLayout* pobjLO
                                       ,QJsonArray& raryCells
                                       ,int* pintRow, int* pintCol) {
        static const char scszLabelProperties[] =
                                "QLabel { text-align:left;"
                                "vertical-align: text-top;"
                                "border:0px;"
                                "color:#000000;"
                                "format:rich;"
                                "text-decoration:none; }";
        static int sintNextID(0);
        if ( pobjParent == nullptr || pobjLO == nullptr ) {
            return;
        }
        Qt::Alignment alignment(Qt::AlignLeft | Qt::AlignTop);
        QString strEquals(clsXMLnode::msccEquals);
        clsXMLnode* pobjNode(nullptr);
        int intCol, intRow;
        intCol = (pintCol != nullptr) ? *pintCol : -1;
        intRow = (pintRow != nullptr) ? *pintRow : 0;
        for( QJsonArray::iterator itCell=raryCells.begin()
                                ; itCell!=raryCells.end()
                                ; itCell++ ) {
            QJsonObject objCell(itCell->toObject());
            QStringList slstAttribs, slstLabel;
            QJsonArray arySubCells;
            int intNodes;
            if ( clsScriptHelper::blnProcessJSON(objCell, slstAttribs, arySubCells) == false ) {
        //Something went wrong!
                continue;
            }
        //Is there a label?
            QString strLabel(clsScriptHelper::strGetAttributeFromList(slstAttribs
                                                                     ,clsXMLnode::mscszAttrLabel));
            if ( strLabel.isEmpty() != true ) {
                intNodes = 2;
                slstLabel << clsCNT::mscszLabel
                          << (clsXMLnode::mscszAttrID
                            + strEquals
                            + QString("lbl%1gnrtd").arg(++sintNextID))
                          << (clsXMLnode::mscszAttrText
                            + strEquals
                            + strLabel)
                          << (clsXMLnode::mscszAttrProperties
                            + strEquals
                            + scszLabelProperties);
            } else {
                intNodes = 1;
            }
            for( int intNode=1; intNode<=intNodes; intNode++ ) {
        //Create node
                QJsonArray* paryCells(nullptr), aryEmpty;
                QStringList* pslstAttrs(nullptr);
                QString strControl, strGroup;
                if ( intNode == 1 && slstLabel.isEmpty() != true ) {
                    pslstAttrs = &slstLabel;
                    paryCells = &aryEmpty;
                } else {
                    pslstAttrs = &slstAttribs;
                    paryCells = &arySubCells;
        //Get control type from cell
                    strControl = clsScriptHelper::strGetAttributeFromList(*pslstAttrs, clsXMLnode::mscszAttrControl);
                    if ( strControl.isEmpty() != true ) {
                        QString strFirst(pslstAttrs->first());
                        if ( strFirst.indexOf(strEquals) == -1 ) {
        //Discard first attribute
                            pslstAttrs->takeFirst();
        //Replace with control type
                            pslstAttrs->insert(0, strControl);
                        }
                    }
                }
                if ( pslstAttrs == nullptr ) {
                    break;
                }
                pobjNode = new clsXMLnode(*pslstAttrs, pobjParent);
                if ( pobjNode == nullptr || pobjNode->blnCanBeVisible() != true ) {
                    continue;
                }
                QWidget* pobjWidget(pobjNode->pobjGetWidget());
                if ( pobjWidget != nullptr ) {
                    const QString cstrName(pobjNode->cstrGetNodeName());
                    clsQtLayout* pobjLayout(nullptr);
                    bool blnAdd(true);
                    if ( cstrName.compare(clsCNT::mscszLayout) == 0 ) {
                        pobjLayout = static_cast<clsQtLayout*>(pobjWidget);
                        pobjWidget = pobjLayout->pobjGetScroller();
                    } else if ( pobjParent != nullptr ) {
                        clsXMLnode* pobjGrandParent(pobjParent->pobjGetParent());
                        if ( pobjGrandParent != nullptr ) {
                            const QString cstrGPname(pobjGrandParent->cstrGetNodeName());
                            if ( cstrGPname.compare(clsCNT::mscszLayout) == 0 ) {
        //The grandparent of this node is a layout, is the parent of this node a layout?
                                const QString cstrPname(pobjParent->cstrGetNodeName());
                                if ( cstrPname.compare(clsCNT::mscszLayout) != 0 ) {
                                    pobjLayout = static_cast<clsQtLayout*>(
                                                    pobjGrandParent->pobjGetWidget());
                                    pobjLayout->addWidget(pobjWidget);
                                    blnAdd = false;
                                }
                            }
                        }
                    }
                    if ( blnAdd == true ) {
                        QGridLayout* pobjGridLO(nullptr);
                        if ( pobjLayout == nullptr ) {
                            pobjGridLO = qobject_cast<QGridLayout*>(pobjLO);
                        }
                        intCol++;
                        if ( pobjGridLO != nullptr ) {
                            pobjGridLO->addWidget(pobjWidget, intRow, intCol, alignment);
                        } else {
                            pobjGridLO = qobject_cast<QGridLayout*>(pobjLO);
                            if ( pobjGridLO != nullptr ) {
                                QString strColSpan(pobjNode->strGetAttribute(clsXMLnode::mscszAttrColSpan));
                                int intColSpan(strColSpan.toInt());
                                if ( intColSpan == 0 ) {
                                    intColSpan = 1;
                                }
                                pobjGridLO->addWidget(pobjWidget, intRow, intCol, 1, intColSpan);
                            } else {
                                pobjLO->addWidget(pobjWidget);
                            }
                        }
                        QString strEOL(pobjNode->strGetAttribute(clsXMLnode::mscszAttrEndOfLine));
                        if ( strEOL.compare(clsXMLnode::mscszTrue) == 0 ) {
                            intRow++;
                            intCol = -1;
                        }
                    }
                }
            }
            if ( arySubCells.size() > 0 ) {
                clsScriptHelper::addNodesToGUI(pobjNode, pobjLO, arySubCells, &intRow, &intCol);
            }
        }
    }
    

    The question is why does the checkbox overlap the row above ?



  • @SPlatten , fixed:
    Screenshot 2021-12-01 at 20.45.56.png
    XML:

    <?xml version="1.0" encoding="utf-8"?>
    <form title="Test form" id="frmTest" hspacing="0" vspacing="0" width="420"
    	  height="360" 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="Surname" id="enSN" eol="true"
    		   cols="24" maxlength="24" accept="alpha_only" dbfield="vcSurName"/>
    	<label text="Sex"/>		   
    	<layout eol="true" height="56" hspacing="0" id="rdoLO" scrollbar="false" 
    			type="grid" vspacing="0" width="72">
    		<buttongroup id="enSEX">
    			<radiobutton id="rdoM" height="28" text="Male" default="true"/>
    			<radiobutton id="rdoF" height="28" text="Female"/>
    		</buttongroup>
    	</layout>
    	<entry control="textedit" label="Address" id="enADR" eol="true"
    		   maxlength="256" accept="alpha_numeric" cols="24" rows="5"
    		   dbfield="vcAddress" properties="margin-bottom:16px;"/>
    	<entry control="checkbox" dbfield="intEmployed" eol="true" id="enEmp"
    		   label="Employed"/>
    	<layout colspan="2" id="btnbarLO" scrollbar="false" type="horizontal">
    		<buttongroup id="enBar">
    			<button id="btnApply" api="applyChanges">
    				<subscriber signal="clicked" target="simon2.js@applyButton"/>
    			</button>
    			<button id="btnUndo" api="undoChanges"/>
    			<button id="btnOK" api="submitAndClose"/>	
    		</buttongroup>
    	</layout>
    	<on saveChanges="Save changes before changing selection?"/>
    	<on setup="simon2.js@setupForm"/>
    </form>
    


  • @SPlatten , fixed:
    Screenshot 2021-12-01 at 20.45.56.png
    XML:

    <?xml version="1.0" encoding="utf-8"?>
    <form title="Test form" id="frmTest" hspacing="0" vspacing="0" width="420"
    	  height="360" 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="Surname" id="enSN" eol="true"
    		   cols="24" maxlength="24" accept="alpha_only" dbfield="vcSurName"/>
    	<label text="Sex"/>		   
    	<layout eol="true" height="56" hspacing="0" id="rdoLO" scrollbar="false" 
    			type="grid" vspacing="0" width="72">
    		<buttongroup id="enSEX">
    			<radiobutton id="rdoM" height="28" text="Male" default="true"/>
    			<radiobutton id="rdoF" height="28" text="Female"/>
    		</buttongroup>
    	</layout>
    	<entry control="textedit" label="Address" id="enADR" eol="true"
    		   maxlength="256" accept="alpha_numeric" cols="24" rows="5"
    		   dbfield="vcAddress" properties="margin-bottom:16px;"/>
    	<entry control="checkbox" dbfield="intEmployed" eol="true" id="enEmp"
    		   label="Employed"/>
    	<layout colspan="2" id="btnbarLO" scrollbar="false" type="horizontal">
    		<buttongroup id="enBar">
    			<button id="btnApply" api="applyChanges">
    				<subscriber signal="clicked" target="simon2.js@applyButton"/>
    			</button>
    			<button id="btnUndo" api="undoChanges"/>
    			<button id="btnOK" api="submitAndClose"/>	
    		</buttongroup>
    	</layout>
    	<on saveChanges="Save changes before changing selection?"/>
    	<on setup="simon2.js@setupForm"/>
    </form>
    

Log in to reply