Important: Please read the Qt Code of Conduct -

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:

    Please 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?


  • Lifetime Qt Champion


    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?

  • Lifetime Qt Champion

    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());
        if(partition.enumerable) {
            _models.last()->setHeaderData(dataModel->columnCount() - 1, Qt::Horizontal, "Action");
        else if(0 == dataModel->rowCount()) {

    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?


  • Lifetime Qt Champion

    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!

Log in to reply