Значения NULL в QSqlRelationalTableModel
Как я могу включить выбор значений NULL в QSqlRelationalModel с помощью привязок PyQt?
Желаемое значение NULL в поле со списком
Я использую QSqlRelationalTableModel платформы PyQt в базе данных SQLite3, чтобы включить поля со списком для выбора отношений внешнего ключа на основе указанного столбца во внешней таблице, вместо простого списка основных идентификаторов (см. Прилагаемый снимок экрана, версия столбца 'относится к таблице' версия 'и полям'name' / 'id').
Однако я не смог найти способ разрешить вставку значений NULL в таблицу, которая мне нужна.
Я могу вставить значение None/NULL в само поле со списком, но при выборе записи оно не обновляет базу данных или даже поле со списком; он просто "возвращается" к текущему выбору.
Итак, на снимке экрана примера: "Advanced" - это текущее значение (точнее, первичный ключ упомянутой записи), и я хочу установить для записи значение "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))