0

I can't figure out the strange display behavior of QSqlRelationalTableModel.
setEditStrategy of the model is set to OnFieldChange. I'm trying to change the values in the cells, but the whole row disappears and you can not change other cells in this row. Why is that?

Before edit

after edit

Here is the code:

from ui_ui import Ui_Form
from PyQt5 import QtWidgets
from PyQt5.QtSql import QSqlRelationalTableModel, QSqlDatabase, QSqlTableModel, 
QSqlRelationalDelegate, QSqlRelation
import sys
import sqlite3

# create db for example, run once
# with sqlite3.connect('db.db') as con:
#     cur = con.cursor()
#     cur.execute('CREATE TABLE IF NOT EXISTS tab ("static_col", "relation_col1", "relation_col2")')
#     cur.execute('CREATE TABLE IF NOT EXISTS relation ("rel")')
#     cur.execute('INSERT INTO tab(static_col) VALUES ("Lorem"), ("ipsum"), ("dolor"),("sit")')
#     cur.execute('INSERT INTO relation(rel) VALUES (69), (322)')

db = QSqlDatabase.addDatabase('QSQLITE')
db.setDatabaseName('db.db')
db.open()

class MainWindow(QtWidgets.QWidget, Ui_Form):

    def __init__(self):
        QtWidgets.QWidget.__init__(self)
        self.setupUi(self)

        table_model = QSqlRelationalTableModel(db=db)
        table_model.setTable('tab')
        table_model.select()
        table_model.setEditStrategy(0)
        self.tableView_1.setModel(table_model)

        delegate = QSqlRelationalDelegate(self.tableView_1)
        table_model.setRelation(1, QSqlRelation('relation', 'rel', 'rel'))
        self.tableView_1.setItemDelegateForColumn(1, delegate)

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    main = MainWindow()
    main.show()
    sys.exit(app.exec_())

ui_ui.py:

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(684, 300)
        self.horizontalLayout = QtWidgets.QHBoxLayout(Form)
        self.horizontalLayout.setObjectName("horizontalLayout")
        self.tableView_1 = QtWidgets.QTableView(Form)
        self.tableView_1.setObjectName("tableView_1")
        self.horizontalLayout.addWidget(self.tableView_1)

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))

try add foreighn key, primary key, change setEditStrategy

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
papadulo
  • 3
  • 2
  • You MUST define primary keys when creating the tables (i.e. in SQL). Otherwise, Qt will be forced to guess, and the results will be undefined. – ekhumoro Mar 16 '23 at 21:11
  • ok I did this CREATE TABLE "relation" ("rel" TEXT, PRIMARY KEY("rel")). Now the value is selected FIRST time, but if you select ANOTHER value in the same cell, the row disappears again. Maybe this is the standard behavior of QSqlRelationalTableModel or am I missing something? – papadulo Mar 17 '23 at 16:01
  • Please consult the [SQLite docs](https://www.sqlite.org/docs.html) on how to properly define [Primary Keys](https://www.sqlite.org/lang_createtable.html#primkeyconst) and [Foreign Keys](https://www.sqlite.org/foreignkeys.html). – ekhumoro Mar 17 '23 at 22:32
  • Your issue is already covered by another question that I answered, so I have linked your question to that. The real causes of the problem are quite complicated to explain, so I don't think it's worth repeating it all here. But putting it as briefly as possible: you must always create SQL tables with both a *primary key* and with columns that all have an *explicit type*. If you don't do this, it may expose some subtle bugs in Qt's implementation of QSqlTableModel, which can be very hard to diagnose. – ekhumoro Mar 18 '23 at 12:36

0 Answers0