QSqlRelationalTableModel

时间:2019-12-19 13:26:03

标签: python sqlite pyqt qsqlrelationaltablemodel

如何使用PyQt绑定在QSqlRelationalModel中启用NULL值选择?

在组合框中输入所需的NULL值

我正在SQLite3数据库上使用PyQt框架的QSqlRelationalTableModel来启用组合框以基于外表中的指定列选择外键关系,而不是基于基本ID的普通表列表(请参阅提供的屏幕快照,列“版本”是指表“版本”,字段是“名称” /“ id”)。

但是,我找不到我需要的允许将NULL值插入表中的方法。

我可以在组合框中插入一个None / NULL值,但是当选择该条目时,它不会更新数据库甚至组合框。它只是“反弹”到当前选择。

因此,在示例屏幕快照中:“高级”是当前值(更确切地说是引用条目的主键),我想将条目设置为“ NULL”。我选择了第一个组合框条目,但该值保留在“高级”上。

我确实尝试实现自己的ItemDelegate类并在那里手动处理。但是,我根本没有设法在数据库中插入NULL值。即使不是通过低级方法。

即使我只是手动使用setNull()方法,在手动检索的记录上也不起作用。

下面是我的自定义ItemDelegate类,它是从QSqlRelationalDelegate派生的。我留下了几种尝试插入NULL值的方法(均无效),并据此进行了注释。

class MyDelegate(QtSql.QSqlRelationalDelegate):
    def __init__(self, parent=None, _db=None):
        super().__init__()
        self.db = _db

    # This is adapted from the original C++ source code in qsqlrelationaldelegate.h
    def createEditor(self, _parent_widget, _option, _index):
        sqlModel = _index.model()
        childModel = None

        if sqlModel:
            col = _index.column()
            childModel = sqlModel.relationModel(col)

        if not childModel:
            textEditor = QPlainTextEdit(_parent_widget)
            return(textEditor)
        else:
            combo = QtSql.QSqlRelationalDelegate.createEditor(self, _parent_widget, _option, _index)
            combo.insertItem(0, "", None) # Here I manually insert an empty value at the top of the combo box - not working, it is only displayed in the combo box
            childModel.insertRow(0) # I also insert a null row into the model, but this does not seem to make a difference / has any effect
            return(combo)

    def setModelData(self, _editor_widget, _model, _index):
        itemType = type(_editor_widget)

        if itemType.__name__ == "QComboBox":
            value = _editor_widget.currentText()
            # manually set to null
            if value == "" or value == None:
                row = _index.row()
                col = _index.column()
                rec = _model.record(row)
                field = rec.field(col)
                tablename = field.tableName()
                val = rec.value(col)
                #childModel = _model.relationModel(col)
                #result_status = rec.setValue(col, None) # Does NOT work
                #result_status = rec.setNull(col) # Does NOT work ?!
                #_model.updateRowInTable(row, rec) # Does NOT work, NULLs the whole row
                #QtSql.QSqlRelationalDelegate.setModelData(self, _editor_widget, _model, _index) # Does NOT work
                _model.setData(_index, None, Qt.DisplayRole) # Does NOT work, does nothing at all
                _model.setData(_index, None, Qt.EditRole)  # Does NOT work, does nothing at all
                _model.submit() # Commit, no effect
                _model.select() # Refresh, no effect
            else:
                QtSql.QSqlRelationalDelegate.setModelData(self, _editor_widget, _model, _index)
        else:
            result_status = QtSql.QSqlRelationalDelegate.setModelData(self, _editor_widget, _model, _index)

    def updateEditorGeometry(self, _editor_widget, _option, _index):
        itemType = type(_editor_widget)
        if itemType.__name__ == "QComboBox":
            _editor_widget.setGeometry(_option.rect)
        else:
            _editor_widget.setGeometry(QRect(_option.rect.left(), _option.rect.top(), 300, 150))

0 个答案:

没有答案