QSqlRelationalDelegate's default value



  • I'm subclassing QSqlRelationalTableModel (with 2 relations) and QTableView. I set QSqlRelationalDelegate for the view. When new (empty) row inserted to model I want relative fields appear as comboboxes immediately, so I call view->openPersistentEditor, comboboxes appears, with first items selected by default (seemingly), but when i sumbit insertion, it fails, because these fields are actually NULL. 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


  • Lifetime Qt Champion

    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 - sublcass QSqlRelationalDelegate and set data to model (curentText of QComboBox) 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 after QTableView::openPersistentEditor and connect it to QSqlRelationalDelegate::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);
    });
    


Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.