setData в QSqlRelationalTableModel возвращает false

Очень поучительная ситуация возникла с использованием setData в переопределенной модели QSqlRelationalTableModel.

фотка 1

Изначально через setData нормально устанавливались все значения (и возвращалось true) кроме установки через setData значения по умолчанию (у нас 0). При установке 0 возвращалось всегда false. У нас на картинке установка в 0 означает очистить поле (поставщик) :

фотка 2

Все становится понятно , если переопределить setData и потом просто зайти отладчиком внутрь функции :

QSqlRelationalTableModel::setData(item , value , role);

Возврат происходит в указанном ниже условии :


bool QSqlRelationalTableModel::setData(const QModelIndex &index, const QVariant &value,
                                       int role)
{
    Q_D(QSqlRelationalTableModel);
    if ( role == Qt::EditRole && index.column() > 0 && index.column() < d->relations.count()
            && d->relations.value(index.column()).isValid()) {
        QRelation &relation = d->relations[index.column()];
        if (!relation.isDictionaryInitialized())
            relation.populateDictionary();
        if (!relation.dictionary.contains(value.toString()))  //  !!!!!!!! здесь !!!!!!!!
            return false;
    }
    return QSqlTableModel::setData(index, value, role);
}

Теперь можно не вникая в суть почему так происходит просто заменить вызов setData на вызов из более раннего предка , то есть из QSqlTableModel:

return QSqlTableModel::setData(item , value , role);

И все заработает как надо , то есть при установке через setData значения 0 будет уже возвращаться true.

Но теперь мы для себя можем открыть некоторые новые подробности использования QSqlRelationalTableModel. А именно , что такое dictionary :

фотка 3

В relation.dictionary у нас присутствуют все 5 значений из relation таблицы. Вот содержание таблицы поставщиков:

фотка 4

relation.dictionary это QHash<QString, QVariant> dictionary в cnherneht QRelation

struct QRelation
{
    public:
        QRelation(): model(0),m_parent(0),m_dictInitialized(false){}
        void init(QSqlRelationalTableModel *parent, const QSqlRelation &relation);

        void populateModel();

        bool isDictionaryInitialized();
        void populateDictionary();
        void clearDictionary();

        void clear();
        bool isValid();

        QSqlRelation rel;
        QRelatedTableModel *model;
        QHash<QString, QVariant> dictionary;//maps keys to display values

    private:
        QSqlRelationalTableModel *m_parent;
        bool m_dictInitialized;
};

Вывод такой : Если dictionary это набор значений id строковое представление связи , то значение "0" не появится в dictionary никогда , так как поле id в таблице поставщиков и не сможет никогда стать равным 0! Все логично.

Вот такой вот нюанс!....

Развиваем класс QSqlTableModel.