PDA

View Full Version : Stuck with tree view/widget



WarOfDevil
10th June 2016, 14:27
Hi guys, it's the first time that i program with QT5 and mysql database also. Before to ask help i will show you the small database that i have to use and the gui of my application:

DB: http://s33.postimg.org/qqht3dc6n/Table.png
GUI: http://s33.postimg.org/cjtc013hr/gui.jpg

1) How can i show in a TreeView/or Widget the category table (without the ID), and if the user click on the plus to expand each parent the child will be the subcategory table (also without ID)?
2) Is it possible for example to retrieve the categoryID when the user click on one element in the tree? I will use the id to run query and display the proper data in the table.

I just want to say that the tree and the table will be read-only, to update or add something in the database i will select a row in the table and press a button to add, remove or update.

I hope someone could help me, it's 3 days that i'm stuck with this, and i didn't find any useful information for the qt website or google.

anda_skoa
11th June 2016, 10:35
1) How can i show in a TreeView/or Widget the category table (without the ID), and if the user click on the plus to expand each parent the child will be the subcategory table (also without ID)?

You will either have to use a QStandardItemModel and fill it with data from SQL queries or derive from QAbstractItemModel and implement a tree model yourself, that can do the queries internally.

Since the latter can be a bit frustrating for someone new to developing models, my suggestion would be to go for the other approach for now.



2) Is it possible for example to retrieve the categoryID when the user click on one element in the tree? I will use the id to run query and display the proper data in the table.

Yes, a model can store multiple data facets, so called roles, per entry. I.e. it can have a string to show in the view and the ID to retrieve in code.

Cheers,
_

WarOfDevil
11th June 2016, 13:25
Thanks for your reply!! I've found a way, since i was stuck from 3 days and i was planning to quit qt5 and go back on c# again.

Thats how i feel the tree:


ui->treeWidget->reset();
ui->treeWidget->setColumnHidden(1, true);
ui->treeWidget->header()->close();

QSqlQuery queryCategory("SELECT * FROM category");

QList< QPair<int, QString> > list;

while (queryCategory.next()) {

int idCategory = queryCategory.value(0).toInt();
QString catName = queryCategory.value(1).toString();

//I need to save the ID to run the second query before to fill the treeWidget
list.append(QPair< int , QString >(idCategory , catName));
}

for(int x = 0; x < list.count(); x++ )
{
QTreeWidgetItem *categoryItem = new QTreeWidgetItem(ui->treeWidget);
categoryItem->setText(0, list[x].second);
categoryItem->setText(1, QString::number(list[x].first));

//Check if we have subcategory
QSqlQuery querySubCategory;
querySubCategory.prepare("SELECT idSubCategory, sub_Name FROM subcategory WHERE idCategory = :id");
querySubCategory.bindValue(":id", list[x].first);
querySubCategory.exec();

while(querySubCategory.next()){

int idSubCategory = querySubCategory.value(0).toInt();
QString subCatName = querySubCategory.value(1).toString();

QTreeWidgetItem *subCategoryItem = new QTreeWidgetItem(categoryItem);
subCategoryItem->setText(0, subCatName);
subCategoryItem->setText(1, QString::number(idSubCategory));
}

}

ui->treeWidget->setEditTriggers(QAbstractItemView::NoEditTriggers) ;

Thats how i retrieve the ID of the item, to run the query for the tableview:


void MainWindow::on_treeWidget_itemDoubleClicked(QTreeW idgetItem *item, int column)
{
//Check if we click a parent or a child
if(item->parent() != NULL){

QString filter = "component.`idSubCategory` = " + item->text(column + 1);

QSqlRelationalTableModel *model = new QSqlRelationalTableModel();
model->setTable("component");
model->setFilter(filter);
model->setRelation(5, QSqlRelation("subcategory", "idSubCategory", "sub_Name"));
model->setRelation(7, QSqlRelation("location", "idLocation", "loc_Name"));

PopulateTableView(model);
}

}

I'm sure that my implementation it's wrong, since you have to create custom model or item but it work for me. The problem is the documentation about this model/view is really bad for a new user that start to use qt5.

anda_skoa
11th June 2016, 14:27
I'm sure that my implementation it's wrong, since you have to create custom model or item but it work for me.

No, that is actually fine, I just forgot about using QTreeWidget instead of QTreeView with a separate model.

What you can do, however, is to store the category integer as an integer instead of having to convert to/from string and using a "hidden" column, by using the QTreeWidgetItem's data/setData:

Storing


QTreeWidgetItem *categoryItem = new QTreeWidgetItem(ui->treeWidget);
categoryItem->setText(0, list[x].second);
categoryItem->setData(0, Qt::UserRole, list[x].first);


Retrieval


int category = item->data(0, Qt::UserRole).toInt();


Btw, in your slot you might not want to create a new model instance every time, otherwise you also need a way to delete the previously created one or you are leaking it.
Better keep the table view model in a member variable and only adjust the filter as needed.

Cheers,
_