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.png

    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?

    Regards,
    Norbert


  • Lifetime Qt Champion

    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?


  • 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());
        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


  • 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
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.