PDA

View Full Version : SQL and QItemDelegate problem



vieraci
29th May 2009, 17:53
I have a table of data with a combo box delegate on one of the columns. I have a problem in creating the delegate efficiently.

The table data is a joined query so I can have the column I want to edit showing the text it relates to instead of the integer code in the table.

I can't use a QSqlRelational* object because the related table data is a subset from a table without a useable index and a some WHERE clauses to filter out unrelated rows. My solution is to load the combo box with a query.

It works, but the combo box is created in the createEditor method, which means every time the field is being edited the query has to be executed. The sensible thing to do here is have the combo box created in the ctr and loaded once...right ?

My problem is I can't work out how to create the combo box in the ctr. QComboBox requires a QWidget as it's parent (which is supplied via createEditor(QWidget *parent... but the ctr code has a QObject parameter as a parent and the code doesn't compile. This is probably a simple answer but I can't think what it may be. Can anyone help please ?

wysota
30th May 2009, 02:58
You don't have to create the combobox in the constructor, You only need to fetch the data there and you can store it for later use. Once you reach createEditor() you just retrieve that data (model, probably) from your storage and set it on the combobox. Actually you should do that in setEditorData() but with createEditor() it will work in most cases as well. Just be aware you can have stale data if you retrieve the contents of the combobox only once.

vieraci
30th May 2009, 05:51
You only need to fetch the data there and you can store it for later use.

Yes I could do that, but I'm trying not to duplicate the data un-necessarily.
The reason I want to create the combo box in the creator is so I could use it like this:


class ComboBoxDelegate : public QItemDelegate
{
Q_OBJECT
public:
//...all the usual declarations...
void addItem(QString text, int index) const;
void setEditColumn(int colNumber) const;
private:
QComboBox *editor;
int editColumn;
};


And then I can fill the combo box with data after I create it...


ComboBoxDelegate *delegate = new ComboBoxDelegate(this);
delegate->addItem(string, int);
delegate->setEditColumn(int);

This way the class is re-useable :cool:

wysota
30th May 2009, 10:25
Yes I could do that, but I'm trying not to duplicate the data un-necessarily.
You are not duplicating data.

And then I can fill the combo box with data after I create it...


ComboBoxDelegate *delegate = new ComboBoxDelegate(this);
delegate->addItem(string, int);
delegate->setEditColumn(int);

This way the class is re-useable :cool:

This way you do duplicate data :-) Just fetch the data into the model in your delegate's constructor and then set the model on a combo box in createEditor or in setEditorData using QComboBox::setModel().

vieraci
31st May 2009, 02:07
Of course ! Why didn't I think of it myself...
Create the QSqlQueryModel in the constructor, then the rest is as you said.

Thanks again wysota.