QTreeWidget not displaying first item in a QList - c++

I'm trying to display items in a QList on a QTreeWidget but no matter how hard i tried i observe that always the first item in the List is not inserted on the treeWidget.
Please i need help. Below is my sample code
void Results::showResults (QList<Semester*>* sList){
for(int i=0; i<sList->count(); i++)
{
ui->treeWidget->addTopLevelItem(sList->at(i)->treeItem);
}
this->show ();
}
NB: every Semester item in the list has a treeItem member.

Related

How to set a new item in tabview Qt, and save the previous ones

When I use Qt tableView, I can just set item in the first row. When I click add, it will cover the former, but not set a new item. Maybe my slot function is incorrect. But I don't know how to handle it.
void Widget::on_addButton_clicked()
{ int i = 0;
EditDialog editDialog(this);
if(editDialog.exec() == 1)
{
model->setItem(i,0,new QStandardItem(editDialog.getID()));
model->setItem(i,1,new QStandardItem(editDialog.getPriority()));
model->setItem(i,2,new QStandardItem(editDialog.getTime()));
}
i++;
}
Please, have a look into doc. QStandardItemModel::setItem():
Sets the item for the given row and column to item. The model takes ownership of the item. If necessary, the row count and column count are increased to fit the item. The previous item at the given location (if there was one) is deleted.
(Emphasizing is mine.)
If a row shall be inserted before end of table (e.g. as first), then it's necessary to do this explicitly.
This can be achieved by calling QStandardItemModel::insertRow() before setting the items.
This could e.g. look like this:
// fills a table model with sample data
void populate(QStandardItemModel &tblModel, bool prepend)
{
int row = tblModel.rowCount();
if (prepend) tblModel.insertRow(0);
for (int col = 0; col < NCols; ++col) {
QStandardItem *pItem = new QStandardItem(QString("row %0, col %1").arg(row).arg(col));
tblModel.setItem(prepend ? 0 : row, col, pItem);
}
}
I took this from an older post of mine. The complete sample can be found in my answer to SO: Stop QTableView from scrolling as data is added above current position.

I'm using qt to design a program and need help because my code is not DRY [duplicate]

I have a gui form, where multiple text boxes are present. I want to put their values inside an array. One way of doing it is by writing something like this
{array element } = ui->text_1->text();
and repeat it for text_2,text_3 upto n.
What I want is to run a loop and replace number portion of text box name in each cycle.
something like this {array element } = ui->text_{This number getting changed }->text();
How can it be done in qt?
There are two ways of doing this.
When you create the UI, instead of using text1, text2, etc. you create an array of QLineEdits (eg. std::vector<QLineEdit>) and then when you want to retrieve their values then simply iterate over this array
Iterate over the children of the container widget. You can get the list of the children using the following (documentation):
QList<QObject *> list = parentWidget->children();
Another option to those listed would be to create an array using an initializer list. Depending on how big the array is (and how often it changes), this might be workable.
QLineEdit* entries[] = { ui->text_0, ui->text_1, ui=>text_2 };
QStringList answers;
for ( int i = 0; i < 3; ++i )
{
answers += entries[i]->text();
}
here is an expanded version of Matyas' solution:
class MyClass : public QWidget
{
QStringList answers;
void FillAnswersList(QObject *base)
{
QLineEdit *lineEdit = qobject_cast<QLineEdit>(base);
if(lineEdit)answers.append(lineEdit->text());
else
{
foreach(QObject *child, base->children())
FillAnswersList(child);
}
}
};
If it is just the number changing, and always incrementing, there is another possible solution using QObject::findChild, which takes a name as a parameter.
QString name_template("text_%1");
QStringList answers;
for(int i = 0; i < MAX_TEXTS; ++i)
{
QLineEdit *edit = ui->findChild<QLineEdit *>(name_template.arg(i));
answers += edit->text();
}

How to cycle through all widget in a QVBoxLayout

I have a QVBoxLayout created through the drag and drop section.
Inside of it AT RUN TIME I insert some widgets with the command
ui->verticalLayout->insertWidget() //using appropriate options.
All widgets I insert are of the same type/class.
I would like to cycle through the inserted widgets in order to perform some actions over them.
I suppose it is really simple but can't seem to find out how...
thank you all!
You can use QLayout::itemAt() to loop on the items of the layout. Then use QLayoutItem::widget() to get the widget:
for(int i = 0; i < layout->count(); ++i)
{
do_something(
layout->itemAt(i)->widget()
);
}
Note that widget() may return a null pointer.

Why do i get a repeated QStringList?

I am writing a Qt application that deals with scheduling employees. The header data for the main QTableView is a pointer to a QStringList. The headerData() function works correctly, but when i add a string to the list elsewhere, it appends the entire list including the new string to the end of the list.
For example, if i have the list 1,2,3 and i append 4 to it, then iterating through the list based on the pointer gives the result 1,2,3,1,2,3,4. I don't know a better way than using pointers to have multiple classes access the same data. Does anyone know how to fix the repeating list?
Example Code
//function to save a new employee in memory
bool EmployeeViewDialog::saveEmployee(Employee *e)
{
employees->insert(e->name,e);
*employeeNames << e->name;
for (int i = 0; i < employeeNames->length(); i++) {
qDebug() << employeeNames->at(i);
}
QList<QStandardItem*> items;
items << new QStandardItem(e->name);
items << new QStandardItem(e->id);
items << new QStandardItem(e->phone);
items << new QStandardItem(e->email);
model->appendRow(items);
return true;
}
The append was just changed to the << method. It is the employeeNames << e->name; line.
The for loop iterates through the list and does the same thing as what happens in the external class.

How to run a loop using gui object names in qt?

I have a gui form, where multiple text boxes are present. I want to put their values inside an array. One way of doing it is by writing something like this
{array element } = ui->text_1->text();
and repeat it for text_2,text_3 upto n.
What I want is to run a loop and replace number portion of text box name in each cycle.
something like this {array element } = ui->text_{This number getting changed }->text();
How can it be done in qt?
There are two ways of doing this.
When you create the UI, instead of using text1, text2, etc. you create an array of QLineEdits (eg. std::vector<QLineEdit>) and then when you want to retrieve their values then simply iterate over this array
Iterate over the children of the container widget. You can get the list of the children using the following (documentation):
QList<QObject *> list = parentWidget->children();
Another option to those listed would be to create an array using an initializer list. Depending on how big the array is (and how often it changes), this might be workable.
QLineEdit* entries[] = { ui->text_0, ui->text_1, ui=>text_2 };
QStringList answers;
for ( int i = 0; i < 3; ++i )
{
answers += entries[i]->text();
}
here is an expanded version of Matyas' solution:
class MyClass : public QWidget
{
QStringList answers;
void FillAnswersList(QObject *base)
{
QLineEdit *lineEdit = qobject_cast<QLineEdit>(base);
if(lineEdit)answers.append(lineEdit->text());
else
{
foreach(QObject *child, base->children())
FillAnswersList(child);
}
}
};
If it is just the number changing, and always incrementing, there is another possible solution using QObject::findChild, which takes a name as a parameter.
QString name_template("text_%1");
QStringList answers;
for(int i = 0; i < MAX_TEXTS; ++i)
{
QLineEdit *edit = ui->findChild<QLineEdit *>(name_template.arg(i));
answers += edit->text();
}