PDA

View Full Version : QComboBox - Delegate - QDataWidgetMapper - QSqlRelationalTableModel



jorge.saridis
28th September 2009, 14:59
Hi, I'm new to Qt4. I'm using Qt4.5

I use QSqlRelationalTableModel to show in a table view a database table with foreign keys to other tables. This works fine.
I created a form to edit each table row. I used a mapper and connected table selection model signal to setCurrentModelIndex mapper slot, this is the code




model = new QSqlRelationalTableModel(this, database);
model->setTable("centros_programas");
model->setRelation(1, QSqlRelation("provincias", "id_provincias", "nombre"));

model->setEditStrategy(QSqlTableModel::OnManualSubmit);
model->select();

model->setHeaderData(0, Qt::Horizontal, QObject::tr("Id"));
model->setHeaderData(1, Qt::Horizontal, QObject::tr("Provincia"));
model->setHeaderData(2, Qt::Horizontal, QObject::tr("Centro/Programa"));
model->setHeaderData(3, Qt::Horizontal, QObject::tr("Tipo"));

ui->comboBoxProvincia->setModel(model->relationModel(1) );
ui->comboBoxProvincia->setModelColumn(model->relationModel(1)->fieldIndex("nombre"));

ui->table->setModel(model);
ui->table->setColumnHidden(0, true);

mapper = new QDataWidgetMapper(this);
mapper->setModel(model);
mapper->addMapping(ui->comboBoxProvincia, model->fieldIndex("id_provincias") );
mapper->addMapping(ui->lineEditCentro, model->fieldIndex("nombre") );
mapper->addMapping(ui->lineEditTipo, model->fieldIndex("tipo") );

mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit);

connect(ui->table->selectionModel(), SIGNAL(currentRowChanged(QModelIndex,QModelIndex)) , mapper, SLOT(setCurrentModelIndex(QModelIndex)));



the thing is: in the form for editing each row, I have a combo box with data from a related table, as you can see in this line:



ui->comboBoxProvincia->setModel(model->relationModel(1) );


I didn't create another model for the combo box.
When I see it running it fills correctly the combo box, but it is not synchronized with data, it always shows first row of the related table.
I was searching and it seems that I need a delegate for it. This is right? I will need a delegate for each combo box? What if I have two or more combo boxes in the form?
Thanks in advance

jorge.saridis
28th September 2009, 16:57
Amazing, I found the answer myself digging in Qt examples. Here is the code:



model->setTable("centros_programas");
model->setRelation(1, QSqlRelation("provincias", "id_provincias", "nombre"));

model->setEditStrategy(QSqlTableModel::OnManualSubmit);
model->select();

model->setHeaderData(0, Qt::Horizontal, QObject::tr("Id"));
model->setHeaderData(1, Qt::Horizontal, QObject::tr("Provincia"));
model->setHeaderData(2, Qt::Horizontal, QObject::tr("Centro/Programa"));
model->setHeaderData(3, Qt::Horizontal, QObject::tr("Tipo"));

ui->comboBoxProvincia->setModel(model->relationModel(1) );
ui->comboBoxProvincia->setModelColumn(model->relationModel(1)->fieldIndex("nombre"));

ui->table->setModel(model);
ui->table->setColumnHidden(0, true);

ui->table->setItemDelegate( new QSqlRelationalDelegate( ui->table ));

mapper = new QDataWidgetMapper(this);
mapper->setModel(model);
mapper->setItemDelegate(new QSqlRelationalDelegate(this));
mapper->addMapping(ui->comboBoxProvincia, 1);
mapper->addMapping(ui->lineEditCentro, model->fieldIndex("nombre") );
mapper->addMapping(ui->lineEditTipo, model->fieldIndex("tipo") );
mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit);

connect(ui->table->selectionModel(), SIGNAL( currentChanged(QModelIndex,QModelIndex) ), mapper, SLOT( setCurrentModelIndex(QModelIndex) ));

ui->table->setCurrentIndex(model->index(0, 0));



I had to set a delegate in two places, the table view and the mapper.
These two lines:


ui->table->setItemDelegate( new QSqlRelationalDelegate( ui->table ));

mapper->setItemDelegate(new QSqlRelationalDelegate(this));


I hope this can help.:)

pcheng
29th December 2012, 14:14
Hi, Jorge.

I tried to follow your code to fix my problem which seems to be similar to what you have.

Here is my code:



// Setup the model to use in the mapper
model = new QSqlRelationalTableModel(this);
model->setTable("Orders");
//model->select();
model->setRelation(7, QSqlRelation("customers", "CustomerNumber", "Name"));
model->setRelation(5, QSqlRelation("employee", "EmployeeNumber", "UserName"));

Qt::SortOrder order = Qt::AscendingOrder;
model->sort(0, order);

ui->customerComboBox->setModel(model->relationModel(7));
ui->customerComboBox->setModelColumn(model->relationModel(7)->fieldIndex("Name"));

ui->employeeComboBox->setModel(model->relationModel(5));
ui->employeeComboBox->setModelColumn(model->relationModel(5)->fieldIndex("LastName"));

// Setup the mapper for the order widgets
mapper = new QDataWidgetMapper(this);
mapper->setSubmitPolicy(QDataWidgetMapper::AutoSubmit);
mapper->setModel(model);
mapper->setItemDelegate(new QSqlRelationalDelegate(this));
mapper->addMapping(ui->idLineEdit, 0);
mapper->addMapping(ui->fullfilledCheckBox,1);
mapper->addMapping(ui->fullfilledDateEdit, 2);
mapper->addMapping(ui->orderDateEdit, 3);
mapper->addMapping(ui->dueDateEdit, 4);
mapper->addMapping(ui->employeeComboBox, model->fieldIndex("Employee_EmployeeNumber"), "currentIndex");
mapper->addMapping(ui->dueTimeEdit, 6);
mapper->addMapping(ui->customerComboBox, model->fieldIndex("customers_CustomerNumber"), "currentIndex");


but my combo boxes do not synchronize with the database. I see the values in the combo boxes but when the mapper loads it shows the first item always. And if I change an item and save it does not change the item.

Any ideas where I am going wrong?

Pericles