Item delegation? how does it work?



  • I'm working on a form which shows and updates a database table T_SRM_cars. This table has a foreign key to a table T_SRM_drivers.
    This form shows the info of one record at a time and has buttons to go to the next or previous record and to add a new record.

    In my form I have a combobox cb_owner which must contain the pseudonym names of all the car owners, which are in the driver table. The combobox shows the name of the driver who owns the specific car. it should be possible to change the owner of the car by selecting a different name in the combobox.

    The program so far works allmost: If the driver_id field in a record in the cars table contains a correct id, the combobox does show the correct owmer, and the combobox does contain the all the pseudonym names from the driver table, but what do i need to do in order to update the driver_id field in the cars table to the driver selected in the combobox.

    Do I need Item delegation? And how should I use it?

    I've seen the books example, but I don't want to use the QTableView.
    I've also seen the SQLWidgetmapper example, but that one does not work correctly. It does not update the addresstype_id in my database.

    I've also thought of using a slot on the combobox. I think the slot on_cb_owner_activated(int index), but I don't know what I should update, when the user selects another driver from the combobox.

    void Form_cars::on_cb_owner_activated(int index)
    {
    //What should I do over here?
    }

    This is the code from the constructor:

    Form_cars::Form_cars(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Form_cars)
    {
    ui->setupUi(this);

    model = new QSqlRelationalTableModel(this);
    model->setTable("T_SRM_cars");
    model->setEditStrategy(QSqlTableModel::OnManualSubmit);
    
    // Remember the indexes of the columns
    driver_id = model->fieldIndex("driver_id");
    
    // Set the relations to the other database tables
    model->setRelation(driver_id, QSqlRelation("T_SRM_drivers", "id", "pseudonym"));
    
    model->select();
    
    ui->cb_owner->setModel(model->relationModel(driver_id));
    ui->cb_owner->setModelColumn(model->relationModel(driver_id)->fieldIndex("pseudonym"));
    
    mapper = new QDataWidgetMapper(this);
    mapper->setModel(model);
    
    mapper->addMapping(ui->le_name, model->fieldIndex("name"));
    mapper->addMapping(ui->cb_owner, driver_id);
    mapper->addMapping(ui->le_brand, model->fieldIndex("brand"));
    mapper->addMapping(ui->le_model, model->fieldIndex("model"));
    
    if (model->rowCount()==0) {
        model->database().transaction();
        if (model->insertRow(model->rowCount())) {
            mapper->toLast();
        } else {
            QMessageBox::warning(this, tr("T_SRM_drivers"),
                                 tr("The database reported an error: %1")
                                 .arg(model->lastError().text()));
        }
    }
    
    mapper->toFirst();
    

    }

    Regards,

    Gerrit Zijlstra


  • Qt Champions 2016

    hi
    you are using OnManualSubmit so i think you need to call
    http://doc.qt.io/qt-5/qsqltablemodel.html#submitAll
    for it to save. (in the cb slot)

    Item delegation ?
    Do you mean a Delegate ?
    http://doc.qt.io/qt-5/qtwidgets-itemviews-stardelegate-example.html
    Delegates are used with views to alter default editing or showing in the/a view.
    Since u are using QDataWidgetMapper and normal widgets, delegates are not
    so common in this context.



  • @mrjj The code for submitting is allready included somewhere else, It is done, everytime one of the other fields in the form is changed by the user. I´ve also tried to put that same code in the slot I mentioned, but I´m missing the connection from the combobox back to the field in the database table. Updating all the other collumns in the databas works correctly. Only the driver_id field does not change, and is left empty when I create a new record.

    If Delegate is not common in this context, then I need to know how to change the contents of the driver_id in my mapping somehow to the id of the selected driver in the combobox.


  • Qt Champions 2016

    Ok,
    Hmm
    Is there anything special with driver_id in the database ?
    Key, constrains etc ?

    As far as I know, it should just work as the other fields.

    Well, delegates are used with views. Its part of the model/view concept so its
    not possible to apply to a normal widget, but it would not really make sense anyway since
    its for altering a views way of handling the data from the model.



  • @mrjj This is how the table is created in sqlite:

    CREATE TABLE IF NOT EXISTS T_SRM_cars (id integer primary key,
    name varchar(30),
    driver_id integer REFERENCES T_SRM_drivers (id),
    brand varchar(20),
    model varchar(30),
    cartype_id integer REFERENCES T_SRM_cartype (id) );

    and yes, the driver_id references the id field from the T_SRM_drivers but it does not have a foreign key constraint yet.
    (The field for cartype_id is not used yet, but will be used the same way as the driver_id. )


  • Lifetime Qt Champion

    Hi,

    I wonder if it's related to QTBUG-16299.

    Can you create a minimal compilable example that shows that behavior ? If so, please add it to the bug report.



  • @SGaist
    Hi,

    I don't know if it's related, but I have created an example program. I don't know how to add it to the bug report, but I will post the files in my dropbox. Maybe you can check if it is related to the QTBUG.

    I work with a sqlite database test.db which is opened in initdb.h. Please change the database to select your own.

    The program creates two tables: drivers and cars. The table cars reference the drivers table. Some records are inserted in each table.

    The form shows the cars table and the combobox shows the lastname of the driver.
    The driver_id in the cars table does not get updated which should be the bug. . .

    In mainwindow.cpp and mainwindow .h I commented out the code for a simple non relational table version. If I comment the relationaltable version out instead of the table version, the program does update the drivers_id field.

    You can download the files from :
    https://www.dropbox.com/sh/4qepkporuk1tndm/AAD1gOhUorK1pTbjl0H2bR2Ha?dl=0

    Regards and thanks for helping again,

    Gerrit Zijlstra
    Hopefull my little example can help fixing a bug, or maybe I'm just forgetting something.


  • Lifetime Qt Champion

    I haven't seen anything obviously wrong with your example so. You should login on the bug report system, and IIRC, you should have a plus sign on the right of the Attachments line



  • @SGaist
    Do you know if there is a workaround on my problem?
    Is there a way to set the value in the model or mapping after the user has selected a row in the combobox, so that the correct value is inserted in the database?

    I have created a new bug report about 4 days ago.
    https://bugreports.qt.io/browse/QTBUG-52986

    It is asigned to someone, but there is no activity on it.
    The person to which it has been assigned, hasn't been active for two weeks. . .

    Regards,

    Gerrit


  • Qt Champions 2016

    @Gerrit-Zijlstra
    I recall tracing such issue some time ago, but I was not able to find the exact problem. Still, judging from the thread it seems I believed there's a bug in the widget mapper's handling of combo boxes. Sadly the original poster didn't share the bug report link.



  • @kshegunov Thanks. It looks like the same isue, but the problem is, that it is not solved and I don't know how to get around it. . .
    I allready made a bug report, with a simple sample program.
    Do you have an idea of how to get around this problem? I really would like to use the combobox for referencing other tables using the id.


  • Qt Champions 2016

    @Gerrit-Zijlstra
    Seeing that Joe's bug report is still hanging out there I don't know what to suggest. As I see it, you have two options: either you give up on that widget and use a custom/manually populated widget, or you try tracing the problem in the debugger, fix it up yourself and upload the patch. Sorry, I know of no workarounds for this. I remember only superficially inspecting the QDataWidgetMapper then, as I had no time to really dig in deeper.


Log in to reply
 

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