Hide column in QAbstractTableModel - qt

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;
}

Related

How to move programmatically to selected row in Qt?

I use QTreeView and QSortFilterProxyModel
// Here I determine the index, that was saved before (_lastAddObjectIndex - QModelIndex)
QModelIndex next_index = _proxyModel->index(_lastAddObjectIndex.row(), 0);
// Here I select the row programmatically, and after that I'd like to move to that row (because table might have many rows)
view->selectionModel()->select(next_index, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows | QItemSelectionModel::SelectCurrent);
I assume by moving, you mean scrolling. If so, you can achieve this by using this API:
view->scrollTo(next_index);
You can even change the scroll hint if you pass a second parameter to the method. This depends on whether you are happy with the default value, which just makes sure that the item is visible.
You can refer to the documentation for fine-tuning this behaviour further in case you need to.

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.

QTableView / QStandardItemModel update without losing selection / sort order

Currently I want to update row items in a QStandardItemModel without losing the sort order and row selection in the respective QTableView.
I have tested two approaches:
Clearing the model by clear() and re-adding the rows "destroys" everything including headers.
Removing and re-adding all rows keeps the headers, but still "destroys" selection and sort order.
I could try to manually to a) remove all rows no longer required and then b) update the items of the changed rows. But is there no easier way?
I don't know, how you sorted your data before the update, but please take a look at the QTableView's sortByColumn() function.
As for the selection, if it still keeps disappearing, you can manually put back your selection, where it should be by:
// You access the selected index when the editing starts
QModelIndex index = table->selectionModel()->currentIndex();
//Later when you finished editing, you can select it again
table->selectionModel()->select(index, QItemSelectionModel::Select);
More about this:
QItemSelectionModel
QTableView
You can either remove the rows no longer required and add the new ones or manually remember the sort order and which items were selected before clearing. I.e. assign a unique ID (one can use setData() with a custom role for that), retrieve that before clearing from the selected items, and reapply the selection after recreating the items.

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

QTreeView: Setting all selected cells to the user-entered value at once

I have a QTreeView which has the ExtendedSelection attribute (users may select more than one non-contiguous range of cells).
I would like my app to allow them to select these multiple cells and then enter a value and have all the cells take that value.
My issue is that I don't know how to get the full range of cells passed to my model. Right now the index that is passed to the setData method is only the active cell, not the full range of selected cells.
In the past, I have had my view store the currently selected range in the model every time it changes, and then use that to control which cells to modify. This seems kind of hacky and I wonder whether anyone has a better and more elegant solution.
I am using PyQt by the way, though I suspect this applies to QT by itself.
Thanks!
I believe you can use selectionModel method of the QAbstractItemView class to iterate through selected indexes and change values of the corresponding cells. Below is a small example:
foreach (QModelIndex index, ui->treeView->selectionModel()->selectedIndexes())
{
qDebug() << "Changing index " << index.row();
ui->treeView->model()->setData(index, "new data");
}
hope this helps, regards

Resources