QSqlRelationalDelegate-subclass-for-QSqlRelationalTableModel

From Qt Wiki
Revision as of 17:33, 12 March 2015 by AutoSpider (talk | contribs) (Decode HTML entity names)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.
This article may require cleanup to meet the Qt Wiki's quality standards. Reason: Auto-imported from ExpressionEngine.
Please improve this article if you can. Remove the {{cleanup}} tag and add this page to Updated pages list after it's clean.

QSqlRelationalDelegate subclass that works with QSqlRelationalTableModel

When you are using a QSqlRelationalTableModel in combination with QSortFilterProxyModel, you lose the automatic combobox that is displayed in a QTableView.

This is a subclass of QSqlRelationalDelegate, that works:

COMMENT: To use it with another proxy model (my own QXTreeProxyModel that converts a table to a tree that can be displayed by QTreeView), I replaced QSortFilterProxyModel by QAbstractProxyModel throughout the code in mysqlrelationaldelegate.cpp; no other changes were necessary. BTW, QXTreeProxyModel is available on https://github.com/Al-/QXTreeProxyModel

Header:

#ifndef MYSQLRELATIONALDELEGATE_H
#define MYSQLRELATIONALDELEGATE_H

#include <QSqlRelationalDelegate>

class mySqlRelationalDelegate : public QSqlRelationalDelegate
{
 Q_OBJECT
public:
 explicit mySqlRelationalDelegate(QObject *parent = 0);

QWidget *createEditor(QWidget *aParent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
 void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
 void setEditorData(QWidget *editor, const QModelIndex &index) const;

signals:

public slots:

};

#endif // MYSQLRELATIONALDELEGATE_H

Source:

  1. include "mysqlrelationaldelegate.h"
  2. include <QSqlRelationalTableModel>
  3. include <QSortFilterProxyModel>
  1. include <QDebug>
  2. include <QSqlRecord>

mySqlRelationalDelegate::mySqlRelationalDelegate(QObject *parent) :

QSqlRelationalDelegate (parent)

{ }

QWidget *mySqlRelationalDelegate::createEditor(QWidget *aParent, const QStyleOptionViewItem &option, const QModelIndex &index) const {

const QSqlRelationalTableModel sqlModel = qobject_cast<const QSqlRelationalTableModel>(index.model());

QSqlTableModel childModel = sqlModel ? sqlModel->relationModel(index.column()) : 0;
if (!childModel )
{
const QSortFilterProxyModel proxyModel = qobject_cast<const QSortFilterProxyModel >(index.model());
if (proxyModel)
{
sqlModel = qobject_cast<const QSqlRelationalTableModel>(proxyModel->sourceModel());
childModel = sqlModel ? sqlModel->relationModel(index.column()) : 0;
}
}

if (!childModel)

{
return QItemDelegate::createEditor(aParent, option, index);
}

QComboBox combo = new QComboBox(aParent);

combo->setModel(childModel);
combo->setModelColumn(childModel->fieldIndex(sqlModel->relation(index.column()).displayColumn()));
combo->installEventFilter(const_cast<mySqlRelationalDelegate>(this));

return combo;

}

void mySqlRelationalDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const {

QString strVal = "";
const QSqlRelationalTableModel sqlModel = qobject_cast<const QSqlRelationalTableModel>(index.model());
if (!sqlModel )
{
const QSortFilterProxyModel* proxyModel = qobject_cast<const QSortFilterProxyModel *>(index.model());
if (proxyModel) {
strVal = proxyModel->data(index).toString();
}
} else {
strVal = sqlModel->data(index).toString();
}

QComboBox combo = qobject_cast<QComboBox>(editor);

if (strVal.isEmpty() || !combo) {
QItemDelegate::setEditorData(editor, index);
return;
}

combo->setCurrentIndex(combo->findText(strVal)); }

void mySqlRelationalDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const {

if (!index.isValid())
return;

QSqlRelationalTableModel sqlModel = qobject_cast<QSqlRelationalTableModel>(model);

QSortFilterProxyModel* proxyModel = NULL;
if (!sqlModel )
{
proxyModel = qobject_cast<QSortFilterProxyModel >(model);
if (proxyModel)
sqlModel = qobject_cast<QSqlRelationalTableModel>(proxyModel->sourceModel());
}

QSqlTableModel *childModel = sqlModel ? sqlModel->relationModel(index.column()) : 0;

QComboBox combo = qobject_cast<QComboBox>(editor);
if (File:SqlModelchildModel || !combo) {
QItemDelegate::setModelData(editor, model, index);
return;
}

int currentItem = combo->currentIndex();

int childColIndex = childModel->fieldIndex(sqlModel->relation(index.column()).displayColumn());
int childEditIndex = childModel->fieldIndex(sqlModel->relation(index.column()).indexColumn());

if (proxyModel) {

proxyModel->setData(index, childModel->data(childModel->index(currentItem, childColIndex), Qt::DisplayRole), Qt::DisplayRole);
proxyModel->setData(index, childModel->data(childModel->index(currentItem, childEditIndex), Qt::EditRole), Qt::EditRole);
} else {
sqlModel->setData(index, childModel->data(childModel->index(currentItem, childColIndex), Qt::DisplayRole), Qt::DisplayRole);
sqlModel->setData(index, childModel->data(childModel->index(currentItem, childEditIndex), Qt::EditRole), Qt::EditRole);
}

}