What is the purpose of TreeView.isTreeNode - qt

The TreeView attaches some properties to its delegate. One of them is isTreeNode. The documentation writes about isTreeNode:
required property bool isTreeNode - Is true if the delegate item represents a node in the tree. Only one
column in the view will be used to draw the tree, and therefore, only
delegate items in that column will have this property set to true. A
node in the tree should typically be indented according to its depth,
and show an indicator if hasChildren is true. Delegate items in other
columns will have this property set to false, and will show data from
the remaining columns in the model (and typically not be indented).
What is the benefit of this property? For me it looks like an alias for column == 0.

It's currently an alias for column === 0, like you say. But it makes the delegate more readable, and opens up for the possibility to rearrange columns at a later point, and improve the support for right-to-left layouts.

Related

Hide column in QAbstractTableModel

I have a self created Qt-Model derieved by QAbstractTableModel. The data behind the model contains multiple QUuid-columns, whose cell-data I need to pass around the application. Due to design-reasons I don't want to show the QUuid-columns to the user, but keep them in the background to always guarantee access to the needed id-columns.
The data is bound to a Qtitan TableView Grid, where I can hide the column, but not totally remove it from the view. I can always reenable the visability which is not what I want.
So my question is if there are any options from the Qt-Model-side to hide a column or to avoid binding it to the view and just keep the data in the background.
You can subtract those columns from the visible columns by returning the column respectively in columnCount.
This would require to either move them to the end, or map the user visible column count to the underlying columns in your data() implementation.
It is probably a bit simpler to move those invisible columns to the end to avoid the mapping, but you can also do the mapping if you like.
int MyModel::columnCount(const QModelIndex& parent) const
{
return allColumns - columnsToHide;
}

How to change the order of QTableView rows by dragging and store the changes to the model?

I want to know how to change the order of QTableView rows by dragging, and store the order changes to the model?
I use QTableView as view and QSqlTableModel as model. I am using Qt 5.15.
I set:
ui->table_view->setSelectionMode(QAbstractItemView::SingleSelection);
ui->table_view->setSelectionBehavior(QAbstractItemView::SelectRows);
ui->table_view->setEditTriggers(QAbstractItemView::NoEditTriggers);
Methods I tried:
1.
ui->table_view->setSectionsMovable(true);
ui->table_view->setDragEnabled(true);
ui->table_view->setDragDropMode(QAbstractItemView::InternalMove);
ui->table_view->setAcceptDrops(true);
It doesn't take effect. The row cannot be dragged.
2.
ui->table_view->verticalHeader()->setSectionsMovable(true);
ui->table_view->verticalHeader()->setDragEnabled(true);
ui->table_view->verticalHeader()->setDragDropMode(QAbstractItemView::InternalMove);
ui->table_view->verticalHeader()->setAcceptDrops(true);
The row can be dragged by vertical header. But the order of changes will not affect the model.
As far as I know the QTableView does not call moveRows method of the model by itself. Instead drag and drop actions call *mimeData methods.
So, one option would be the following:
In your model you need to implement mimeData and dropMimeData functions. When you drag and drop a row the view will ask for mimeData() of the given row. If you are sure that you need only internal moves you can encode the selected row indices to QMimeData. Then in the dropMimeData() you decode the indices that were selected and use them to call your moveRows() implementation. Return false from this function to prevent removing of the moved out rows.
Another option can be to override the QTableView methods such as dropEvent() in a way, that it calls the model moveRows() method directly.

Different Qt::CheckStateRole for different views?

Currently I have a simple setup where I maintain a list of bools corresponding to each item in my ListModel:
http://programmingexamples.net/wiki/Qt/ModelView/StringListModelCheckable
However, now what I want to do is have two such lists bools, say IsHot and IsLarge. Then I want to have a ListView that displays each string with a checkbox for one of the bools (the "Hot" view), and a separate ListView that displays each string with a checkbox for the other bool (the "Large" bool). Any hints on how to go about this?
Make your model a table, return the data in two different columns, the cells in these columns will be checkable.
On your list views, call QListView::setModelColumn to set the column the list view displays.
If you want to synchronise scrolling between the lists, you would then be better using a QTableView, so that rows would match up.
Edit to add more detail on returning text and check state.
To return a text and the state of a checkbox from the model you return different data for different roles from the [data] function on your model.
From the manual for Qt::ItemDataRole:
Qt::DisplayRole The key data to be rendered in the form of text. (QString)
Qt::CheckStateRole This role is used to obtain the checked state of an item. (Qt::CheckState)
Both columns in your model would return the same data (the name) for DisplayRole but different data for CheckStateRole

Qt error "persistent model indexes corrupted" why?

I've a problem with my Qt/interview application. I use QTreeView to display tree data. I implemented my own model based on QAbstractItemModel.
I get a following error prior to application crash. It happens often after I add new record.
Could You explain to me what is the meaning of this error. What is a QPersistentModelIndex ?
I'm not using QPersistentModelIndex in my code.
ASSERT failure in QPersistentModelIndex::~QPersistentModelIndex: "persistent model indexes corrupted"
Thanks.
QPersistentModelIndexes are (row, column, parent) references to items that are automatically updated when the referenced items are moved inside the model, unlike regular QModelIndex. For instance, if you insert one row, all existing persistent indexes positioned below the insertion point will have their row property incremented by one.
You may not use them directly, but QTreeView does, to keep track of expanded items and selected items, for example.
And for these persistent indexes to be updated, you have to call the functions QAbstractitemModel::beginInsertRows() and endInsertRows() around the actual row insertion(s) when you add new records.
See the end of the section about subclassing model classes for details: http://doc.trolltech.com/latest/qabstractitemmodel.html#subclassing
I found this method QAbstractItemModel::persistentIndexList and I'm
wondering what indexes it should return. All of them ?
Should this method return all nodes currently visible in the TreeView ?
That method returns only the indexes for which a QPersistentIndexModel was created and is still in scope (as a local variable, a class member, or in a QList<QPersistentIndexModel> for example).
Expanded or selected nodes are not necessarily currently visible, so you can't (and shouldn't anyway) assume anything about what these persistent indexes are used for.
You just have to keep them updated, and you only need to use persistentIndexList for big changes in the model, like sorting (see QTreeWidget internal model : QTreeModel::ensureSorted(link)), for smaller incremental changes you have all the beginXxxRows/beginXxxColumns and endXxxRows/endXxxColumns methods.

Setting multiple selection in QTreeView

I have a need here regarding multiple selection of items in the QTreeView. I have two widgets, QTreeView on left and another QGLWidget on the right. If I do a multiple selection, I must highlight the items in the glwidget. Vice versa, I need to highlight the items in the tree view if multiple selection is done on the glwidget. Currently, I am able to update single item by setting the current index of the tree view. Any ideas on how to update the selection of multiple items on the tree view with multiple selection on glwidget?
You can use the tree view's item selection model (treeView->selectionMode(), of type QItemSelectionModel). It has a signal selectionChanged() you can connect to to receive tree view selection changes and apply them to the GL view.
When receiving selection events from the GL view, you can use QItemSelectionModel::select() to propagate them to the tree view.
To enable multiselection on your treeview, call setSelectionMode( MultiSelection ).
Frank was faster, but I still post my (untested) code example for adding an item to the current selection:
treeView->selectionModel()->select(
treeView->model()->index(row, column, parent),
QItemSelectionModel::SelectCurrent);
There are other selection modes too, see the QItemSelectionModel reference. SelectCurrent is a short-hand for Select | Current, so means update current selection by selecting the given items. It does not mean "select as current selection" (replacing previous selection).
In Python (PyQt6) I do :
ui.my_treeView.setSelectionMode(ui.my_treeView.selectionMode().MultiSelection)
It works well.

Resources