PDA

View Full Version : Displaying a model as a QTreeView & Table.



gcain
16th October 2013, 00:44
Hi Forum,

I have a database that has two tables representing a list of jobs and a list of tasks for each job.

My goal is to display this information in a QTreeView as well as in QTableView. Initially however, I want to display the QTreeView in two different ways.
1. Jobs with their tasks as children.
2. Three Task Categories with the tasks in those categories as children.

Currently I am constructing a QStandardItemModel like this;



QStringList jobs = api->jobs(); // Returns a QStringList of the database tables: e.g. job_id|JobTitle|task_id|TaskTitle

QStringList headerLabels;
headerLabels << "Date" << "UUID" << "Assigned" << "Due Date" << "Status";
m_stdmodel->setHorizontalHeaderLabels(headerLabels);

foreach(const QString& job, jobs) {
QList <QStandardItem *> jobItem;
jobItem << new QStandardItem(QIcon(":/png/64x64/accept.png"), api->jobTitle(job));
QStringList tasks = api->tasksByJob(job);
foreach(const QString& task, tasks) {
QList<QStandardItem*> items;
items << new QStandardItem(QIcon(":/png/64x64/remove.png"), api->taskTitle(task));
items << new QStandardItem(task);
items << new QStandardItem(api->taskAssignee(task));
items << new QStandardItem(api->taskDue(task));
items << new QStandardItem(api->taskStatus(task));
//
jobItem.at(0)->appendRow(items); // append child items to top-level item
}
m_stdmodel->appendRow(jobItem);
}
// Set the mode here so we can set different
// models for different views.
table.setModel(m_stdmodel);
table.hideColumn(1);
table.expandAll();


The problem with this is that I am technically viewing a copy of the data and not the data from the database itself. IMHO, this breaks the whole concept of using a model/view architecture.
It also means that any other views into the data are out of sync with each other.

My question is; what models should I be using and how do I keep the various views in sync?
I have decided I should be using a QAbstractProxyModel but I can't work out how to correctly implement the mapTo/FromSource so that the hierarchy is correct.

Thanks.

pkj
16th October 2013, 05:11
Use QSortFilterProxyModel ... mapTo/FromSource have been implemented in it.
To keep data in sync, you need a single source of data on which both models work upon.

gcain
16th October 2013, 06:12
Use QSortFilterProxyModel ... mapTo/FromSource have been implemented in it.
Thanks.


To keep data in sync, you need a single source of data on which both models work upon.

Would I have a single model that the other two models proxy data from?

pkj
16th October 2013, 06:32
If you can describe a datastructure with a single tree then go for a single model. It will solve all your problems of syncing. And is a very neat solution too.
But with your problem, I cannot see a single tree datastructure modelling your problem. If you cannot have a single tree, then there is no other way than to have two independent models, looking at the two trees, and a Mediator like class managing the sync between the two data structures. The models will have made public their begininsertrows etc, which the mediator uses to insert rows in the two trees and informs the other model about the changes.

gcain
16th October 2013, 08:15
If you can describe a datastructure with a single tree then go for a single model. It will solve all your problems of syncing. And is a very neat solution too.
But with your problem, I cannot see a single tree datastructure modelling your problem. If you cannot have a single tree, then there is no other way than to have two independent models, looking at the two trees, and a Mediator like class managing the sync between the two data structures. The models will have made public their begininsertrows etc, which the mediator uses to insert rows in the two trees and informs the other model about the changes.

Are you able to link me to an example or some documentation on how the mediator class would be structured? I am struggling to wrap my head around it.

I am guessing you would just have opposing signals and slots updating the other model on change.
This solution does seem quite simple really.

Maybe I'll go write a simple implementation of what I want and see how it works actually...

Thanks.