2

I'm using QComboBox to select unit (an arbitrary property of the object) from Units table. The problem is that object in my data model can have no unit (NULL in the table), in which case QComboBox shows value happened on top of the list. Select 'none' is not possible.
What do you suggest to add NULL support? I have few versions:

  1. Insert special record in Units table named '--' or 'N/A'. Not exactly NULL - will have its own id.
  2. Set items in QComboBox and update model manually. Possible but tedious - goodbye automatic update of unit list.

What else is possible - subclassing QComboBox (overriding what)? I don't see anything similar to setEditorData/setModelData like in QAbstractItemDelegate to control items.

alxx
  • 9,897
  • 4
  • 26
  • 41
  • Let's forget for the moment about the `QComboBox` and tell me when you are getting the data from the database how are you storing the `NULL` in your object representation? – Karlson Jan 27 '12 at 17:40
  • Data is pulled from database and stored in the collections of objects (manually instead of using any ORM, but I'm working on it.) Then, `QStandardItemModel`'s are created and filled with this data to be presented for editing. I have list of editable objects (called Enums), user can select row in the `QTableView` and use editor with combobox to edit Enum. NULL obviously comes from DB as null QVariant and is then stored as integer 0 (I have rule that id <= 0 are invalid.) – alxx Jan 30 '12 at 08:10
  • Did not come to mind until I got explained situation to somebody :) Of course, when item is selected in the list I can do with editor whatever I need to, including adding NULL option. Sorry for this slowpoking, I'm closing the question. – alxx Jan 30 '12 at 09:33

1 Answers1

1

You can subclass the model, so that data will return a special value for NULL and then setData will check for the special value and substitute a NULL.

Example sketch of code:

class MyModel : public QSqlTableModel
{
  Q_OBJECT
  public:
    MyModel();
    virtual QVariant data(const QModelIndex& index, int role = Qt::DisplayRole) const;
    virtual bool setData(const QModelIndex &index, const QVariant &value, int role);
};

QVariant MyModel::data(const QModelIndex& idx, int role)
{
  QVariant var = QSqlTableModel::data(idx, role);
  if (var.isNull())
    var = QVariant(QString("NULL"));
  return var;
}

bool MyModel::setData(const QModelIndex& idx, const QVariant& value, int role)
{
  QVariant var(value);
  if (var == QString("NULL"))
    var == QVariant(record().field(idx.column()).type());
  return QSqlTableModel::setData(idx, var, role);
}
Silas Parker
  • 8,017
  • 1
  • 28
  • 43
  • 1
    Not sure how to apply that... For example, there is three units in Units table: m, s and g. Combobox shows the m, s, g and I want to add 'none' on top of the list. `MyModel::data` will be called three times to pull out m, s and g, and I need some event from where it is called to add 'none'. – alxx Jan 24 '12 at 05:11