Extending QSqlRelationalTableModel



  • I 'm trying to extend QSqlRelationalTableModel, in order to try make some changes, e.g return two fields:

    model->setRelation(clientIndex,
               QSqlRelation("clients", "id", "firstname,lastname"));
    

    The above code returns only the first field.
    I want to make it return both fieds, firstname and lastname.

    What I 've done so far (my class is named QSqlRelationalTableModelB):
    qsqlrelationaltablemodelb.h

    #ifndef QSQLRELATIONALTABLEMODELB_H
    #define QSQLRELATIONALTABLEMODELB_H
    
    #include <QtSql/qsqlrelationaltablemodel.h>
    
    class QSqlRelationalTableModelB : public QSqlRelationalTableModel {
      Q_OBJECT
    public:
      explicit QSqlRelationalTableModelB(QString text, QSqlRelationalTableModel *parent = 0);
    };
    
    #endif // QSQLRELATIONALTABLEMODELB_H
    

    qsqlrelationaltablemodelb.cpp

    #include "QSqlRelationalTableModelB.h"
    
    QSqlRelationalTableModelB::QSqlRelationalTableModelB(QString text, QSqlRelationalTableModel *parent) :
      QSqlRelationalTableModel(parent)
    {
        QDebug() << "QSqlRelationalTableModelB!!!"
    }
    

    I create a new instance of the class like this:

    RTMB = new QSqlRelationalTableModelB("hi", this);
    

    But when I build it, I get an error:

      error: C2664: 'QSqlRelationalTableModelB::QSqlRelationalTableModelB(QString,QSqlRelationalTableModel *)' : 
      cannot convert parameter 2 from 'RepairDevices *const ' to 'QSqlRelationalTableModel *'
    Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
    


  • change explicit QSqlRelationalTableModelB(QString text, QSqlRelationalTableModel *parent = 0);
    to explicit QSqlRelationalTableModelB(QString text, QObject*parent = 0);



  • VRonin, I made the change you suggested, but now I get another error:

    repairdevices.obj:-1: error: LNK2019: unresolved external symbol "public: __thiscall QSqlRelationalTableModelB::QSqlRelationalTableModelB(class QString,class QObject *)" (??0QSqlRelationalTableModelB@@QAE@VQString@@PAVQObject@@@Z) referenced in function "public: __thiscall RepairDevices::RepairDevices(void)" (??0RepairDevices@@QAE@XZ)
    

  • Moderators

    @Panoss Did you apply this change to the method definition in cpp file as well?



  • jsulm you 're right, I hadn't.
    Idid, and now my files are:

    qsqlrelationaltablemodelb.h:

    #ifndef QSQLRELATIONALTABLEMODELB_H
    #define QSQLRELATIONALTABLEMODELB_H
    
    #include <QtSql/qsqlrelationaltablemodel.h>
    
    class QSqlRelationalTableModelB : public QSqlRelationalTableModel {
      Q_OBJECT
    public:
      explicit QSqlRelationalTableModelB(QString text, QObject *parent = 0);
    
    };
    
    #endif // QSQLRELATIONALTABLEMODELB_H
    
    

    qsqlrelationaltablemodelb.cpp:

    #include "QSqlRelationalTableModelB.h"
    #include "QDebug"
    
    QSqlRelationalTableModelB::QSqlRelationalTableModelB(QString text, QObject *parent) :
      QSqlRelationalTableModel(parent)
    {
        qDebug() << "QSqlRelationalTableModelB!!!"
    }
    

    But now I get the error:

    repairdevices.obj:-1: error: LNK2019: unresolved external symbol "public: __thiscall QSqlRelationalTableModelB::QSqlRelationalTableModelB(class QString,class QObject *)" (??0QSqlRelationalTableModelB@@QAE@VQString@@PAVQObject@@@Z) referenced in function "public: __thiscall RepairDevices::RepairDevices(void)" (??0RepairDevices@@QAE@XZ)
    


  • I deleted all files from the debug folder, rebuilt it and run fine!
    I suppose it was some file in the debug folder.



  • I took a look in the file qsqlrelationaltablemodel.
    As you see, it 's the 5.0.2 version because I use Qt 5.0.2.
    As you also see, it has 749 lines of code...
    I 'm a little bit desperate...:)



  • I 'm trying to override function setRelations.

    .h:

    #ifndef QSQLRELATIONALTABLEMODELB_H
    #define QSQLRELATIONALTABLEMODELB_H
    
    #include <QtSql/qsqlrelationaltablemodel.h>
    
    class QSqlRelationalTableModelB : public QSqlRelationalTableModel {
        Q_OBJECT
    public:
        explicit QSqlRelationalTableModelB(QString text, QObject *parent = 0);
        virtual void setRelation(int column, const QSqlRelation &relation);
    };
    
    #endif // QSQLRELATIONALTABLEMODELB_H
    

    .cpp:

    #include "QSqlRelationalTableModelB.h"
    #include "QDebug"
    
    QT_BEGIN_NAMESPACE
    
    QSqlRelationalTableModelB::QSqlRelationalTableModelB(QString text, QObject *parent) :
      QSqlRelationalTableModel(parent)
    {
        qDebug() << "QSqlRelationalTableModelB!!!";
    }
    
    void QSqlRelationalTableModelB::setRelation(int column, const QSqlRelation &relation)
    {
        Q_D(QSqlRelationalTableModelB);
        if (column < 0)
            return;
        if (d->relations.size() <= column)
            d->relations.resize(column + 1);
        d->relations[column].init(this, relation);
    }
    
    
    QT_END_NAMESPACE
    

    I get quite a few errors:

    ...\qsqlrelationaltablemodelb.cpp:14: error: C2065: 'QSqlRelationalTableModelBPrivate' : undeclared identifier
    
    ...\qsqlrelationaltablemodelb.cpp:14: error: C2059: syntax error : 'const'
    
    ...\qsqlrelationaltablemodelb.cpp:17: error: C2065: 'd' : undeclared identifier
    

    And a few more...



  • I think it has to do with Q_D(QSqlRelationalTableModelB).
    I read some things here, but I can't say I understand much.


  • Qt Champions 2016

    Q_D is the d-pointer expansion macro. Long story short, to use that with the private object of the relational table model Qt has, you need to create one additional class that inherits from QSqlRelationalTableModelPrivate (QT += sql-private) and implement a constructor that passes an instance from the inherited private class to the parent class, i.e. QSqlRelationTableModel. Now, that's hacking into the Qt's internals (which is not documented and breaks binary compatibility) and I'm not completely convinced you really need it. What exactly are you striving to accomplish?

    I think you actually want to use QSqlRelationalDelegate instead.



  • I 'm trying this which I describe in my first post:

    @Panoss said in Extending QSqlRelationalTableModel:

    I 'm trying to extend QSqlRelationalTableModel, in order to try make some changes, e.g return two fields:

    model->setRelation(clientIndex,
               QSqlRelation("clients", "id", "firstname,lastname"));
    

    The above code returns only the first field.
    I want to make it return both fieds, firstname and lastname.


  • Qt Champions 2016

    @Panoss said in Extending QSqlRelationalTableModel:

    I 'm trying this which I describe in my first post

    Yes, I read it, but I didn't understand. Do you mind explaining further? What do you want to return both fields? How would this in your mind work (i.e. how is one relation going to be associated with two tables? And what code returns only the first field, it's just not clear.



  • I have 2 tables:

    1. devices (fields: id, brand, client_id). The 3nd is foreign key.
    2. clients(with fields: id, firstname, lastname).
      They are connected with devices.client_id = client.id.

    When a device is displayed, I want to be also displayed firstname and lastname from clients.


  • Lifetime Qt Champion

    Hi,

    What about using a proxy model that would put these two fields together ?



  • I don't know what a proxy model is.
    Could you give me an example?


  • Lifetime Qt Champion



  • I restart this topic (as I had been distracted by other parts of the code):
    I 'm trying to make it with QSortFilterProxyModel (I hope this is the correct way).
    Let me remind you what I'm trying to acomplish:

    I have 2 tables:

    1. devices (fields: id, brand, client_id). The 3nd is foreign key.
    2. clients(with fields: id, firstname, lastname, address).
    They are connected with devices.client_id = client.id.
    

    This is how I make the model ('model' is the model for devices):

    model = new QSqlRelationalTableModel(this);
    model->setTable("devices");
    

    When a device is displayed, I also display lastname from clients in a combo with this code:

    QSqlTableModel *relClientModel = model->relationModel(clientIndex);
    ui.client_id_cbo->setModel(relClientModel);
    ui.client_id_cbo->setModelColumn(relClientModel->fieldIndex("lastname"));  
    

    So, how can I display and firstname and address from clients in two textboxes?

    Like a master/detail form, where master is 'devices' and detail is 'clients', showing one client only (while, usually, in detail we have a list).



  • Finally, it was proved to be a lot simpler, using the model of the combo:

    row = ui.client_id_cbo->currentIndex();    
    QModelIndex idx = ui.client_id_cbo->model()->index(row, 0); // first column
    QString client_firstname = idx.sibling(idx.row(), 1).data().toString();
    QString client_address = idx.sibling(idx.row(), 3).data().toString();
    ui.client_firstname_txt->setPlainText(client_firstname);
    ui.client_address_txt->setPlainText(client_address);
    

Log in to reply
 

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