Dynamically create multiple layouts
-
wrote on 18 Feb 2023, 04:00 last edited by
I am setting dynamically the contents of multiple layouts. I have 15 horizontal layout set out in my ui file, i want to set their values dynamically in code but i am only able to set one layout per time.
The code is belowui->horizontalLayout_6->addWidget(CourseCodeLabel); ui->horizontalLayout_6->addWidget(CourseCodeLineEdit); ui->horizontalLayout_6->addWidget(CourseGradeLabel); ui->horizontalLayout_6->addWidget(CourseGradeComboBox); ui->horizontalLayout_7->addWidget(CourseCodeLabel); ui->horizontalLayout_7->addWidget(CourseCodeLineEdit); ui->horizontalLayout_7->addWidget(CourseGradeLabel); ui->horizontalLayout_7->addWidget(CourseGradeComboBox);
After running this, only the second layout content shows, how can i get the two to show at same time?
-
I am setting dynamically the contents of multiple layouts. I have 15 horizontal layout set out in my ui file, i want to set their values dynamically in code but i am only able to set one layout per time.
The code is belowui->horizontalLayout_6->addWidget(CourseCodeLabel); ui->horizontalLayout_6->addWidget(CourseCodeLineEdit); ui->horizontalLayout_6->addWidget(CourseGradeLabel); ui->horizontalLayout_6->addWidget(CourseGradeComboBox); ui->horizontalLayout_7->addWidget(CourseCodeLabel); ui->horizontalLayout_7->addWidget(CourseCodeLineEdit); ui->horizontalLayout_7->addWidget(CourseGradeLabel); ui->horizontalLayout_7->addWidget(CourseGradeComboBox);
After running this, only the second layout content shows, how can i get the two to show at same time?
wrote on 18 Feb 2023, 08:08 last edited by@SamuelAdesola
You are trying to add the same widget instances to multiple layouts. Widgets are actual objects, they cannot "be in two places at one time" since they are not quantum objects! Your second set of statements move the widgets fromhorizontalLayout_6
tohorizontalLayout_7
.You have to create separate, additional widgets if you want to place them on other layouts.
-
@SamuelAdesola
You are trying to add the same widget instances to multiple layouts. Widgets are actual objects, they cannot "be in two places at one time" since they are not quantum objects! Your second set of statements move the widgets fromhorizontalLayout_6
tohorizontalLayout_7
.You have to create separate, additional widgets if you want to place them on other layouts.
wrote on 18 Feb 2023, 17:18 last edited by@JonB How can i go about creating multiple objects. I tried using vectors of object but not working.
-
@JonB How can i go about creating multiple objects. I tried using vectors of object but not working.
wrote on 18 Feb 2023, 17:27 last edited by@SamuelAdesola
Do all your layouts contain the same bunch of widgets ? -
@SamuelAdesola
Do all your layouts contain the same bunch of widgets ?wrote on 18 Feb 2023, 18:00 last edited by SamuelAdesola@mpergand Yes
The same set of widgets repeated in a certain number of times based on the user's input -
@mpergand Yes
The same set of widgets repeated in a certain number of times based on the user's inputwrote on 18 Feb 2023, 18:26 last edited by mpergand@SamuelAdesola
One possibility:const int LayoutCount=7; struct LayoutWidgets { QHBoxLayout* layout; QLabel* CourseCodeLabel; QLineEdit* CourseCodeLineEdit; QLabel* CourseGradeLabel; QComboBox* CourseGradeComboBox; }; LayoutWidgets layoutArray[LayoutCount]; ... // populate layoutArray for(int i=0; i<LayoutCount; i++) { QHBoxLayout* layout=this->findChild<QHBoxLayout*>(QString("horizontalLayout_%1").arg(i+1)); if(layout==nullptr) { // not found continue; } layoutArray[i].layout=layout; layoutArray[i].CourseCodeLabel=new QLabel; layoutArray[i].CourseCodeLineEdit=new QLineEdit; layoutArray[i].CourseGradeLabel=new QLabel; layoutArray[i].CourseGradeComboBox=new QComboBox; // populate QLayout layout->addWidget(layoutArray[i].CourseCodeLabel); layout->addWidget(layoutArray[i].CourseCodeLineEdit); layout->addWidget(layoutArray[i].CourseGradeLabel); layout->addWidget(layoutArray[i].CourseGradeComboBox); }
Of course not tested !
-
@SamuelAdesola
One possibility:const int LayoutCount=7; struct LayoutWidgets { QHBoxLayout* layout; QLabel* CourseCodeLabel; QLineEdit* CourseCodeLineEdit; QLabel* CourseGradeLabel; QComboBox* CourseGradeComboBox; }; LayoutWidgets layoutArray[LayoutCount]; ... // populate layoutArray for(int i=0; i<LayoutCount; i++) { QHBoxLayout* layout=this->findChild<QHBoxLayout*>(QString("horizontalLayout_%1").arg(i+1)); if(layout==nullptr) { // not found continue; } layoutArray[i].layout=layout; layoutArray[i].CourseCodeLabel=new QLabel; layoutArray[i].CourseCodeLineEdit=new QLineEdit; layoutArray[i].CourseGradeLabel=new QLabel; layoutArray[i].CourseGradeComboBox=new QComboBox; // populate QLayout layout->addWidget(layoutArray[i].CourseCodeLabel); layout->addWidget(layoutArray[i].CourseCodeLineEdit); layout->addWidget(layoutArray[i].CourseGradeLabel); layout->addWidget(layoutArray[i].CourseGradeComboBox); }
Of course not tested !
wrote on 18 Feb 2023, 18:31 last edited by@mpergand
Thanks
I will implement this and get back to you. -
@mpergand
Thanks
I will implement this and get back to you.wrote on 18 Feb 2023, 18:36 last edited byrepeated in a certain number of times based on the user's input
the number of layouts is not fixed ?
-
wrote on 18 Feb 2023, 18:45 last edited by
@mpergand said in Dynamically create multiple layouts:
const int LayoutCount=7;
struct LayoutWidgets
{
QHBoxLayout* layout;
QLabel* CourseCodeLabel;
QLineEdit* CourseCodeLineEdit;
QLabel* CourseGradeLabel;
QComboBox* CourseGradeComboBox;
};LayoutWidgets layoutArray[LayoutCount];
...
// populate layoutArray
for(int i=0; i<LayoutCount; i++)
{
QHBoxLayout* layout=this->findChild<QHBoxLayout*>(QString("horizontalLayout_%1").arg(i+1));
if(layout==nullptr)
{
// not found
continue;
}
layoutArray[i].layout=layout;
layoutArray[i].CourseCodeLabel=new QLabel;
layoutArray[i].CourseCodeLineEdit=new QLineEdit;
layoutArray[i].CourseGradeLabel=new QLabel;
layoutArray[i].CourseGradeComboBox=new QComboBox;// populate QLayout layout->addWidget(layoutArray[i].CourseCodeLabel); layout->addWidget(layoutArray[i].CourseCodeLineEdit); layout->addWidget(layoutArray[i].CourseGradeLabel); layout->addWidget(layoutArray[i].CourseGradeComboBox); }
It worked Perfectly. Thanks very much
-
repeated in a certain number of times based on the user's input
the number of layouts is not fixed ?
wrote on 18 Feb 2023, 19:57 last edited by@mpergand Max is 15, I created the 15 spaces in the from ui. The number created on at runtime depends on the user input
-
Hi,
Since you have a dynamic number of objects, you should use a QVector to hold the exact number of them.
That will simplify your code and memory handling.
-
@mpergand Max is 15, I created the 15 spaces in the from ui. The number created on at runtime depends on the user input
wrote on 18 Feb 2023, 20:19 last edited by mpergand@SamuelAdesola
As @SGaist said use QVector:LayoutWidgets layoutArray[LayoutCount];
QVector<LayoutWidgets> layoutArray;then first create a LayoutWidgets instance in the loop:
for(int i=0; i<LayoutCount; i++)
{
layoutArray<<LayoutWidgets;
....Max is 15, I created the 15 spaces in the from ui
Why not create this layouts in code as well?
-
@SamuelAdesola
One possibility:const int LayoutCount=7; struct LayoutWidgets { QHBoxLayout* layout; QLabel* CourseCodeLabel; QLineEdit* CourseCodeLineEdit; QLabel* CourseGradeLabel; QComboBox* CourseGradeComboBox; }; LayoutWidgets layoutArray[LayoutCount]; ... // populate layoutArray for(int i=0; i<LayoutCount; i++) { QHBoxLayout* layout=this->findChild<QHBoxLayout*>(QString("horizontalLayout_%1").arg(i+1)); if(layout==nullptr) { // not found continue; } layoutArray[i].layout=layout; layoutArray[i].CourseCodeLabel=new QLabel; layoutArray[i].CourseCodeLineEdit=new QLineEdit; layoutArray[i].CourseGradeLabel=new QLabel; layoutArray[i].CourseGradeComboBox=new QComboBox; // populate QLayout layout->addWidget(layoutArray[i].CourseCodeLabel); layout->addWidget(layoutArray[i].CourseCodeLineEdit); layout->addWidget(layoutArray[i].CourseGradeLabel); layout->addWidget(layoutArray[i].CourseGradeComboBox); }
Of course not tested !
wrote on 22 Feb 2023, 16:03 last edited by@mpergand
I successfully implemented this but came across a problem along the way, i have tried solving it but i am still not getting it.After dynamically creating the objects using QVector, I wanted to access the element of the object using another funtion when a button is clicked but the program keeps crashing.
How can i access these elements in another function?
I want to be able to do something like
qDebug() << layoutArray[1].CourseCodeLabel->text();
-
@mpergand
I successfully implemented this but came across a problem along the way, i have tried solving it but i am still not getting it.After dynamically creating the objects using QVector, I wanted to access the element of the object using another funtion when a button is clicked but the program keeps crashing.
How can i access these elements in another function?
I want to be able to do something like
qDebug() << layoutArray[1].CourseCodeLabel->text();
wrote on 22 Feb 2023, 16:12 last edited by@SamuelAdesola
Use the debugger and show us the stack trace. -
wrote on 23 Feb 2023, 09:06 last edited by
I will implement this and get back to you.
-
@mpergand
I successfully implemented this but came across a problem along the way, i have tried solving it but i am still not getting it.After dynamically creating the objects using QVector, I wanted to access the element of the object using another funtion when a button is clicked but the program keeps crashing.
How can i access these elements in another function?
I want to be able to do something like
qDebug() << layoutArray[1].CourseCodeLabel->text();
wrote on 23 Feb 2023, 10:10 last edited by@SamuelAdesola
If you have code likelayoutArray[1].CourseCodeLabel->text()
which crashes you will doubtless find thatlayoutArray[1]
does not exist orlayoutArray[1]->CourseCodeLabel
is null/not valid. Which a stack trace should indeed reveal. -
I will implement this and get back to you.
wrote on 23 Feb 2023, 12:15 last edited by@jonezzpeterr
Ok, I'll be looking forward to it -
@SamuelAdesola
If you have code likelayoutArray[1].CourseCodeLabel->text()
which crashes you will doubtless find thatlayoutArray[1]
does not exist orlayoutArray[1]->CourseCodeLabel
is null/not valid. Which a stack trace should indeed reveal.wrote on 23 Feb 2023, 14:00 last edited by@JonB
Can I make layoutArray a global variable so if I assign it in a function, I can access it in another function. One function is to show the user the forms layouts and another is to use the inputed data to do some calculations. I should have put them in same function but the calculation aspect automatically use the empty fields when a button is press. There are 2 buttons, one to show the user the fields and the other to make use of the inputed data for some calculations. -
@JonB
Can I make layoutArray a global variable so if I assign it in a function, I can access it in another function. One function is to show the user the forms layouts and another is to use the inputed data to do some calculations. I should have put them in same function but the calculation aspect automatically use the empty fields when a button is press. There are 2 buttons, one to show the user the fields and the other to make use of the inputed data for some calculations.wrote on 23 Feb 2023, 14:10 last edited by JonB@SamuelAdesola
Make it a class member variable, rather than global, and you can access it in any class method. The fact that it is array is not relevant. And btw if it's a plain C array better use aQVector
, say. -
@SamuelAdesola
Make it a class member variable, rather than global, and you can access it in any class method. The fact that it is array is not relevant. And btw if it's a plain C array better use aQVector
, say.wrote on 23 Feb 2023, 20:49 last edited by@JonB @mpergand @jonezzpeterr @SGaist
Thanks very much for the support, I think i have achieve quite a lot of those giving tough time.
As @SGaist said I am using QVector and as @JonB said i declare it as a class member variable
QVector<LayoutWidgets> layoutArray;
Because the size will be set at run time base on user input, i resize the vector in a function
layoutArray.resize(LayoutCount);
and i am able to make calls to my class setters to set the values in layoutArray and use another getter function to access the set values
1/20