QSqlRelationalDelegate's default value
-
I'm subclassing
QSqlRelationalTableModel
(with 2 relations) andQTableView
. I setQSqlRelationalDelegate
for the view. When new (empty) row inserted to model I want relative fields appear as comboboxes immediately, so I callview->openPersistentEditor
, comboboxes appears, with first items selected by default (seemingly), but when i sumbit insertion, it fails, because these fields are actuallyNULL
. So i'm forced to open comboboxes and choose item, even if it's first and appears as already selected. Can I somehow evade this excess action, if I want first item to be selected for insertion? Thanks -
Hi,
In that case, why not populate the new row with default values ?
-
@SGaist
Because it already shows default value, and because this is foreign key field and first (default) value in parent table can be changed, so manual row populating would include accessing to first record of parent tables and I think it's redundant (because, once again,QComboBox
already shows default value). Is there a way to achieve this? Now I one see possible solution - sublcassQSqlRelationalDelegate
and set data to model (curentText
ofQComboBox
) when editor is created or shown, but maybe this can't be achieved -
I made it this way:
QWidget* MySqlRelationalDelegate::createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const { auto editor = QSqlRelationalDelegate::createEditor(parent, option, index); setModelData(editor, const_cast<QAbstractItemModel*>(index.model()), index); return editor; }
Is it appropriate? Can it be acieved somehow without
const_cast
? -
Maybe more appropriate way would be to subclass
QTableView
, define signal afterQTableView::openPersistentEditor
and connect it toQSqlRelationalDelegate::setModelData
? -
So my final solution is:
class SqlRelationalDelegate : public QSqlRelationalDelegate { Q_OBJECT public: StorageSqlRelationalDelegate(QObject* parent = nullptr) : QSqlRelationalDelegate(parent) {} QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index) const override { editor = QSqlRelationalDelegate::createEditor(parent, option, index); return editor; } void destroyEditor(QWidget* editor, const QModelIndex& index) const override { QSqlRelationalDelegate::destroyEditor(editor, index); this->editor = nullptr; } QWidget* getEditor() const { return editor; } private: mutable QWidget* editor = nullptr; }; ... class TableView : public QTableView { Q_OBJECT public: StorageTableView(QWidget* parent = nullptr) {} void openPersistentEditor(const QModelIndex &index) { QTableView::openPersistentEditor(index); emit persistentEditorOpened(index); } signals: void persistentEditorOpened(const QModelIndex &index); }; ... connect(view, &TableView::persistentEditorOpened, [view] (const QModelIndex& index) { auto model = view->model(); auto delegate = qobject_cast<SqlRelationalDelegate*>(view->itemDelegate(index)); if (!delegate) qFatal("Delegate cast error"); delegate->setModelData(delegate->getEditor(), model, index); });