Extend QSqlTableModel & Update model data;



  • Hi,
    because I'm new to Qt I need some design suggestions.
    I have persistent data stored in a database and dynamic data calculated at run-time. I want to show both in a QTableview, but I don't want to store the dynamic data in the database to reduce unnecessary transactions. Should I create two models or should I use a QProxyModel use the setModel function to include sql-data and add columns for dynamic data or should I extend the QSqlTableModel directly?
    The next problem is I don't know how to update the dynamic data inside the model. If I receive new data for an specific object how I can address it in the model to update it. The setData function only work on QModelIndex. I know the column but not the row the create the index and I want to avoid a search every time.
    Thanks.


  • Lifetime Qt Champion

    Hi and welcome to devnet,

    Since it's computed from the database content then I'd go with the QSqlTableModel subclass.

    When setData is called the index received contains both the row and column so you know exactly which cell has been modified. Just update the content of the computed column and emit the dataChanged signal with both parameters pointing your computed cell.

    Hope it helps



  • @SGaist
    Thanks for your help. If I inherit form QSqlTableModel and add an extra column which function I have to overwrite, only data, headerData and setData?
    Yes of course, if I call setData with a specific QModelIndex the signal dataChanged knows the index of the updated cell, but my problem is the step before. I receive position updates every second. The update contains an id corresponding the primary key of an database object and an new position. Now I want to update the appropriate row in the model, so I need a mapping from the id to the row. Or it's possible build a model containing the whole object and connect the update signal to the object slot?


  • Lifetime Qt Champion

    Also columnCount, otherwise your column won't be shown.

    AFAIK, you currently have to do that by hand e.g. using a QHash.



  • Thanks for your help.
    I decide to inherit from QSortFilterProxyModel, extend it to add additional columns and set the sourceModel to QSqlTableModel .

    class ExtraColumnProxyModel : public QSortFilterProxyModel
    {
      Q_OBJECT
    public:
      ExtraColumnProxyModel(QObject* parent = 0);
    
      Qt::ItemFlags flags(const QModelIndex &index) const;
    
      QVariant headerData( int section
                         , Qt::Orientation orientation
                         , int role = Qt::DisplayRole
                         ) const;
    
      QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
    
      int columnCount(const QModelIndex &parent = QModelIndex()) const;
    
      QModelIndex index( int row
                       , int column
                       , const QModelIndex& parent = QModelIndex()
                       ) const;
    
      void appendColumn(QString columnName);
    
      QHash<int, QByteArray> roleNames() const;
    
    private:
      QHash<int, QByteArray> m_roles;
      QVector<QString> headerDataVector = QVector<QString>();
    };
    

  • Lifetime Qt Champion

    So it's working like you wanted it ?



  • Yes, the model works correctly. Thanks.
    If I want to access the data stored in the extraColumns and I the only thing I get is a identifier-string. I have to create a QHash<QString, QModelIndex> (update it on model change) to get the correct index and a QMap<QModelIndex, $Data> to store and access the values. Or is there a cleaner solution?


  • Lifetime Qt Champion

    Are you moving rows around ?



  • If not, is there a simpler solution?
    I was thinking of filter and sort functionality.


  • Lifetime Qt Champion

    You could put that information at the same index using a custom role but it might be slower to get to the right index when searching for it.



  • Sounds like what I'm looking. Can you please describe in more detail what is to be done for or post a link to a describtion?

    Best regards


  • Lifetime Qt Champion

    You can all setData from your model and change the last parameter to a custom value e.g. Qt::UserRole + 1. Define that value in your class so you can easily re-use it.



  • Sorry, I was looking for an example , but found nothing on the internet. Can you explain to me the usage of it by short example ?


  • Lifetime Qt Champion

    An example of myModel->setData(myCustomValue, Qt::UserRole + 1); ?


Log in to reply
 

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