In-line control in QTableModel
-
Hi Folks,
in my application I have to use QTableViews, and they content is coming from SQL database via QSqlTableModel and every records could be deleted or duplicated depends on the user.
The following is only a sample image from google to represent what I want:
http://www.apphp.com/php-datagrid/images/screenshots/inline_editing.pngPlease consider the rightmost column: it is only for display the "delete" control, and I guess that isn't the part of the data model.
The question is how can I extend the model behind of the view to store additional columns for my "delete" and "copy" buttons?
Regards,
Norbert -
Hi,
Usually you would put a proxy model between your original model and the view so you don't fiddle with the QSqlRelationalTableModel that handles the data from your database. In that model you will return a column count higher than the original model to put your additional columns.
Hope it helps
-
Hi,
thanks for the reply, it sounds good enough. Which methods and how should I implement / reimplement for use QAbsrtactProxyModel in a QTableView? As I see, its sublcassing from QAbstractItemModel (which is a general model for every view classes, like lists and grids as well) as the QAbstractTableModel as well, but as I know, the QAbstractTableModel were designed to use in grids.
Could you provide any example, where the QAbsrtactProxyModel class is subclassed to create model for grids?
-
The proxy model doesn't (and shouldn't) care what the underlying model is. Whether it's a list or table model doesn't really mater. It's a man in the middle. Take a look at QIdentityProxyModel. It's just a layer between the view and the model.
-
Hi SGaist,
thank you for your suggestions. I change my application regarding them, and I got something like this:
_models.append(TableModelPtr(new QIdentityProxyModel())); QSqlTableModel* dataModel = new QSqlTableModel(this, ProjectManager::get().database()); dataModel->setTable(partition.name); dataModel->setEditStrategy(QSqlTableModel::OnManualSubmit); dataModel->select(); _models.last()->setSourceModel(dataModel); if(partition.enumerable) { _models.last()->insertRow(dataModel->rowCount()); _models.last()->insertColumn(dataModel->columnCount()); _models.last()->setHeaderData(dataModel->columnCount() - 1, Qt::Horizontal, "Action"); } else if(0 == dataModel->rowCount()) { dataModel->insertRow(0); }
The "_models" variable is an array of models, where the user can select the desired model from.
You see, I try to insert a row and column into the proxymodel (whitin the conditions), but as I see, they will be inserted into the sourcemodel instead of to be present in the QIdentityModel instance.
I don't know, how can I avoid this? The newly inserted columns targets the view to draw QPushButton onto them by the following code:const QModelIndex modelIndex = _models[_currentIndex]->index(_models[_currentIndex]->rowCount() - 1, _models[_currentIndex]->columnCount() - 1); _ui->_TVPartitions->setIndexWidget(modelIndex, createAddControl());
How can I solve this task? Could you provide and example, suggestions, or whatever else?
Regards,
Norbert -
You should subclass QIdentityProxyModel and re-implement column count to return the source model count + 1 and data to handle that new column and otherwise return the source model data. So you will make the view think there's a new column.
Watch out about setIndexWidget, if your model contains lots of data you'll have a performance hit. having e.g. a thousand entries will yield the creation of a thousand widgets.
-
This post is deleted!