PDA

View Full Version : QTreeView to display only selected subset of items in model



frankb
3rd January 2014, 17:46
Hello,

how can I connect a QSqlTableModel to a QTreeView in such a way, that only selected items (selected via code) are shown in the QTreeView? Usually I would connect the model to the QTreeView like so:


treeView = new QTreeView();
treeView->setModel(model);

This results in the QTreeView displaying all rows of the underlying SQL table. I would like to be able to only let the QTreeView display items that are set by some function:


void MainWindow::addEntry(QModelIndex index)
{
// treeView does know the model, and thus can handle the QModelIndex internally
treeView->addItem(index);
}

My first intention was to use QTreeWidget instead and manage all items manually. But I would really like to use the same model for another widget. Once the data in the second widget is changed, the QTreeView should also be updated automatically. If I would use a QTreeWidget instead, I would have to tell the other widget's parent (main window) about any changes, and manually propagate them to the QTreeView (and other potential widgets that are not connected to the model). Is there any way to achieve this behavior with the model/view approach?

Thank you!

d_stranz
3rd January 2014, 17:54
Use a QSortFilterProxyModel-based class between your SQL table model and your tree view. Reimplement the QSortFilterProxyModel::filterAcceptsColumn() and QSortFilterProxyModel::filterAcceptsRow() methods to include only the items you want.

frankb
3rd January 2014, 18:03
Thank you for your answer! Sounds great, but how would I add specific rows in my addEntry() slot? It's supposed to add items on user input. For example, a user double-clicks an entry in a QTableView. I would connect the signal like so:


connect(tableView, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(addEntry(QModelIndex)));

How would I dynamically adjust the QSortFilterProxyModel filtering (i.e. QSortFilterProxyModel::filterAcceptsRow()) to add this item?

EDIT: I could manage a list of visible items in the QSortFilterProxyModel to keep track of all visible items, right? Is that a sane way of doing it? Or is there a more convenient way? Thanks again!

d_stranz
3rd January 2014, 18:22
You need to derive your own class from QSortFilterProxyModel and set it up so it keeps track of which items are selected. Either that, or implement a QItemSelectionModel on the view from which the user is selecting items to add to the tree, and set that on the proxy. You're basically setting up a pipeline: your SQL model is the initial source, your tree is the final destination. In between you layer filters and selection models so that what ends up in the tree is whatever the user has selected from the source model via the view they are choosing them from.

Remember that QModelIndex instances are transient; you can't store them anywhere. So if you store the selected items in the proxy, you'll need to store a list of row numbers, not model indexes.

frankb
4th January 2014, 01:30
Works like a charm, thank you! I am using a QList of QPersistentModelIndex to keep track of selected items. From my understanding QPersistentModelIndex works just as well as storing rows though.