How to use code to add items dynamically to UI and position them correctly in Qt ?
-
Let's say I have a UI like this:
I want the Subject combo-box to determine how many Difficulties combo-box and Number of questions it should have. For example, if the Subject combo-box has a variable of 5, it will add 5 more combo-boxes and line edits nicely and neatly like this:
Later, I will add more child combo-boxes like this
So how do I implement this, with layouts ( in c++ ) ? Please give some examples/code if possible
-
@Dante-Pham Ok so basically you make a layout (or in your case you probably already have one in your GUI, then you add the widgets you need to the layout. I'll approach this as if you have nothing in your main widget so you understand the concept. I write all my GUIs in code, almost never use Qt Designer any more.
void YourWidget::YourWidget() { auto vbox = new QVBoxLayout() for (auto i=0;i<numCombos;++i) { auto hb = new QHBoxLayout(); auto cb = new QComboBox(); // setup your cb here with items, etc... // add combo and line edit to your horizontal box hb->addWidget(cb); hb->addWidget(new QLineEdit()); // add your hbox to your vertical box layout vbox->addLayout(hb); } // set your vbox as your layout for your widget setLayout(vbox); // this reparents everything to your widget so no need to track pointers and clean up }
In your case above you will already have a vboxlayout in your gui so instead of creating
vbox
you would just access yours from the ui pointer. -
@ambershark
Everytime I update the variable in the Subject combo-box, everything in the Difficulties group ( combo boxes and labels ) should be able to be cleared in order to create new ones. Using your method will makes it impossible to do that. Do you have any other ideas ?Additionally, normally you right click on the items in the ui to create signals and slots for them. How do you do that if you create them dynamically like so ?
Also, as you can see on the 3rd picture some combobox has childrens who has indentations. How to implement that ?
-
@Dante-Pham said in How to use code to add items dynamically to UI and position them correctly in Qt ?:
should be able to be cleared in order to create new ones.
Once a Widget is inserted into a layout, the layout owns it.
To take it back, use TakeAt() . Only way.
http://doc.qt.io/qt-5/qlayout.html#takeAtAdditionally, normally you right click on the items in the ui to create signals and slots for them. How
do you do that if you create them dynamically like so ?You use the connect statement
QObject::connect(&a, &Counter::valueChanged, &b, &Counter::setValue);
Since you need the pointer, you will do this when you new them.
http://doc.qt.io/qt-5/signalsandslots.htmlAlso, as you can see on the 3rd picture some combobox has childrens who has indentations. How to implement that ?
I would use a widget as row. In this row, i inset the layout, and the combobox etc.
I would then set Widgets margin for left side to something higher and it would
appear indented. layout->setContentsMargins(X,0,0,0); -
@Dante-Pham said in How to use code to add items dynamically to UI and position them correctly in Qt ?:
@ambershark
Everytime I update the variable in the Subject combo-box, everything in the Difficulties group ( combo boxes and labels ) should be able to be cleared in order to create new ones. Using your method will makes it impossible to do that. Do you have any other ideas ?Additionally, normally you right click on the items in the ui to create signals and slots for them. How do you do that if you create them dynamically like so ?
Also, as you can see on the 3rd picture some combobox has childrens who has indentations. How to implement that ?
Yea you can do what mrjj said and takeAt() to remove widgets then delete them, or you can just take out each layout row (the hboxes) and delete those. That will auto clean the widgets.
Also if you have a max number in your subjects drop down you can create all your widgets and then simply show or hide them as necessary. This will be a lot faster and less taxing on the cpu.
To connect signals:
auto widget = new QPushButton(); connect(widget, SIGNAL(clicked()), this, SLOT(myButtonClicked());