PDA

View Full Version : Problems with QSqlRelationalTableModel



waldo1979
6th April 2009, 07:11
I'm having a bit of trouble with QSqlRelationalTableModel. Every time I submitAll(), the value of a relational column (Customers.name) is written to my table instead of the integer key (Projects.customerId). Below is some pseudo code. Any suggestions for how to debug and/or resolve this issue?

The field correctly reads (customerNameLineEdit gets populated with the correct value) however a problem occurs on write. I've tried with and without foreign keys. I'm using MySql as my database.



CREATE TABLE IF NOT EXISTS `projects` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`customerId` int(11) NOT NULL,
`industryId` int(11) DEFAULT NULL,
`opCode` varchar(255) DEFAULT NULL,
`statusId` int(11) DEFAULT NULL,
`startDate` date DEFAULT NULL,
`endDate` date DEFAULT NULL,
`notes` text,
PRIMARY KEY (`id`),
UNIQUE KEY `opCode` (`opCode`),
KEY `customerId` (`customerId`),
KEY `status` (`statusId`),
KEY `industryId` (`industryId`),
KEY `customerId_2` (`customerId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=39 ;

CREATE TABLE IF NOT EXISTS `customers` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` text,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=16 ;


// SETUP THE TABLE
projectsModel.setTable("Projects");
projectsModel.setRelation(1, QSqlRelation("Customers", "id", "name"));
projectsModel.setRelation(2, QSqlRelation("refIndustries", "naicCode", "name"));
projectsModel.setRelation(4, QSqlRelation("refStatuses", "id", "name"));
projectsModel.select();

mapper = new QDataWidgetMapper(this);
mapper->setModel(projectModel);
mapper->setItemDelegate(new QSqlRelationalDelegate(mapper));
mapper->addMapping(ui->customerNameLineEdit, projectModel->fieldIndex("Customers_Name"));
mapper->addMapping(ui->industryComboBox, projectModel->fieldIndex("refIndustries_name"));
mapper->addMapping(ui->projectCodeLineEdit, projectModel->fieldIndex("opCode"));
mapper->addMapping(ui->statusComboBox, projectModel->fieldIndex("refStatuses_name"));
mapper->addMapping(ui->startDateDateEdit, projectModel->fieldIndex("startDate"));
mapper->addMapping(ui->endDateDateEdit, projectModel->fieldIndex("endDate"));
mapper->addMapping(ui->notesTextEdit, projectModel->fieldIndex("notes"));
mapper->setSubmitPolicy(QDataWidgetMapper::ManualSubmit);
mapper->setCurrentIndex(rowId);


// LATER I DO A SUBMIT LIKE THIS
mapper->submit())
projectModel->submitAll()

janus
7th April 2009, 07:52
Hi,

take a look at the sqlwidgetmapper exmaple. As far as I remember you need to set the comboBox Model to the relationModel of the specific column.

waldo1979
7th April 2009, 17:32
I was trying to map a QLineEdit, but I'm guessing this is not supported with the mapper. I have it working now but I had to combine two SQL tables, which I was trying to avoid. I'm guessing there might be a way to get a QComboBox to behave more like a QLineEdit, but I'll have to come back to that later.

Another interesting feature is that the mapper looses it's index after submits and commits. The work around is to save the index before hand and then reset it after all submits/commits.

certqt
3rd December 2010, 15:08
Hi, sorry for the late reply to this post but I was struggling with the same problem and think I have worked out the solution.

The problem seems to be that the QDataWidgetMapper doesn't re-populate itself correctly after updates to the model when the submit policy is QDataWidgetMapper::AutoSubmit. This is true of both the standard item delegate and the QSqlRelationalDelegate (which just calls the standard delegate if it is not populating a combo box anyway).

To get a QLineEdit to work well with a QDataWidgetMapper and a QRelationalTableModel it is necessary to subclass either QItemDelegate or QSqlRelationalDelegate as follows:

void MyItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
if (!strcmp(editor->metaObject()->className(),"QLineEdit")) {
QLineEdit *le = qobject_cast<QLineEdit *>(editor);
le->setText(index.data().toString());
}
else
QItemDelegate::setEditorData(editor, index);
}
Then install MyItemDelegate in the same way as you installed QSqlRelationalDelegate:

mapper->setItemDelegate(new MyItemDelegate);
Hope this helps someone, or if I have got something wrong I would be happy to hear why.

frankb
5th January 2014, 01:58
Sorry for digging out this old thread, but I have the same issue. Unfortunately subclassing QSqlRelationalDelegate as described above did not work for me: my QLineEdit is still empty.

Anything else I could do?

Sorry for digging out this old thread, but I have the same issue. Unfortunately subclassing QSqlRelationalDelegate as described above did not work for me: my QLineEdit is still empty.

Anything else I could do?

Added after 45 minutes:

After struggling with this issue for several days, I finally figured out that using
mapper->addMapping(someLineEdit, model->fieldIndex("fieldName")); does not work. I already had issues using QSqlTableModel::fieldIndex() before, but it worked for the relational QComboBox, so I didn't think this could be the issue. After switching to plain ints, everything works as expected. Sorry again for digging out this thread.