Feb-05-2022, 09:15 AM
Ok, I found it!
I subclassed the QSqlRelationalDelegate:
I subclassed the QSqlRelationalDelegate:
# Created by: PyQt6 UI code generator 6.2.3 # # WARNING: Any manual changes made to this file will be lost when pyuic6 is # run again. Do not edit this file unless you know what you are doing. from PyQt5.QtCore import QRegExp from PyQt5.QtGui import QRegExpValidator from PyQt6 import QtCore, QtWidgets from PyQt6.QtCore import Qt, QObject from PyQt6.QtWidgets import QMainWindow, QPushButton, QDialog, QVBoxLayout, QLineEdit, QComboBox from PyQt6.QtWidgets import QWidget from PyQt6.QtWidgets import QApplication from PyQt6.QtSql import QSqlRelation, QSqlRelationalTableModel, QSqlTableModel, QSqlRelationalDelegate import copy from PyQt6.QtSql import QSqlRelationalDelegate from PyQt6.QtGui import QPixmap class myWindow(QMainWindow): """A window to show the articles available""" def __init__(self, parent=None): """Initializer.""" super().__init__(parent) #create and init db init_db() ###################################################### ##################### V I E W ###################### ###################################################### self.setWindowTitle("Articles") self.resize(550, 250) self.centralWidget = QWidget() self.setCentralWidget(self.centralWidget) self.layout = QVBoxLayout() # add QTableView self.ArticlesTableView = QtWidgets.QTableView(self) self.ArticlesTableView.setObjectName("ArticlesTableView") self.layout.addWidget(self.ArticlesTableView) # add button self.button = QPushButton(self) self.button.setObjectName("button") self.button.setText("Edit positions") self.layout.addWidget(self.button) self.button.clicked.connect(self.button_clicked) # set central the self.layout self.centralWidget.setLayout(self.layout) ###################################################### #################### M O D E L ##################### ###################################################### self.ArticlesModel = QSqlRelationalTableModel(self.ArticlesTableView) self.ArticlesModel.setEditStrategy(QSqlTableModel.EditStrategy.OnFieldChange) self.ArticlesModel.setTable("articles") self.ArticlesTableView.setModel(self.ArticlesModel) position_idx = self.ArticlesModel.fieldIndex("position") self.ArticlesModel.setRelation(position_idx, QSqlRelation("positions", "id", "name")) if not self.ArticlesModel.select(): print(self.ArticlesModel.lastError()) self.ArticlesTableView.setItemDelegate(myDelegate(self.ArticlesTableView)) self.ArticlesModel.setHeaderData(position_idx, QtCore.Qt.Orientation.Horizontal, "position") def button_clicked(self): # open form Positions which displays the positions myDialog = Positions() # Should recieve signal (signalRefreshArticlesModel) from Position form myDialog.signalRefreshArticlesModel.connect(self.RefreshArticlesModel) myDialog.exec() @QtCore.pyqtSlot() def RefreshArticlesModel(self): print("Articles Form: Refresh Articles Model called!") if not self.ArticlesModel.select(): print("Articles Form: " + self.ArticlesModel.lastError()) ########################################################## class Ui_dialog_add_new(object): def setupUi(self, dialog_in): dialog_in.setObjectName("dialog_in") dialog_in.resize(400, 146) self.setWindowTitle("Add new position") self.setModal(True) print("fieldName 0=" + self.model.record().fieldName(0) + " fieldName 1=" + self.model.record().fieldName(1)) self.verticalLayout_3 = QtWidgets.QVBoxLayout(dialog_in) self.verticalLayout_3.setObjectName("verticalLayout_3") self.verticalLayout_2 = QtWidgets.QVBoxLayout() self.verticalLayout_2.setObjectName("verticalLayout_2") self.verticalLayout = QtWidgets.QVBoxLayout() self.verticalLayout.setObjectName("verticalLayout") self.horizontalLayout_2 = QtWidgets.QHBoxLayout() self.horizontalLayout_2.setObjectName("horizontalLayout_2") self.positionLabel = QtWidgets.QLabel(dialog_in) self.positionLabel.setObjectName("positionLabel") self.horizontalLayout_2.addWidget(self.positionLabel) self.positionEdit = QtWidgets.QLineEdit(dialog_in) self.positionEdit.setObjectName("positionEdit") self.horizontalLayout_2.addWidget(self.positionEdit) self.horizontalLayout_2.setStretch(0, 1) self.horizontalLayout_2.setStretch(1, 4) self.verticalLayout.addLayout(self.horizontalLayout_2) self.horizontalLayout_3 = QtWidgets.QHBoxLayout() self.horizontalLayout_3.setObjectName("horizontalLayout_3") self.authorLabel = QtWidgets.QLabel(dialog_in) self.authorLabel.setObjectName("authorLabel") self.horizontalLayout_3.addWidget(self.authorLabel) #self.authorNameCombo = QtWidgets.QComboBox(dialog_in) #self.authorNameCombo.setObjectName("authorNameCombo") #self.horizontalLayout_3.addWidget(self.authorNameCombo) self.horizontalLayout_3.setStretch(0, 1) self.horizontalLayout_3.setStretch(1, 4) self.verticalLayout.addLayout(self.horizontalLayout_3) spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Expanding) self.verticalLayout.addItem(spacerItem) self.horizontalLayout = QtWidgets.QHBoxLayout() self.horizontalLayout.setObjectName("horizontalLayout") spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Policy.Expanding, QtWidgets.QSizePolicy.Policy.Minimum) self.horizontalLayout.addItem(spacerItem1) self.okButton = QtWidgets.QPushButton(dialog_in) self.okButton.setObjectName("okButton") self.okButton.setText("Ok") self.okButton.clicked.connect(self.okButton_clicked) self.horizontalLayout.addWidget(self.okButton) self.cancelButton = QtWidgets.QPushButton(dialog_in) self.cancelButton.setObjectName("cancelButton") self.cancelButton.setText("Cancel") self.cancelButton.clicked.connect(self.cancelButton_clicked) self.horizontalLayout.addWidget(self.cancelButton) self.verticalLayout.addLayout(self.horizontalLayout) self.verticalLayout_2.addLayout(self.verticalLayout) self.verticalLayout_3.addLayout(self.verticalLayout_2) QtCore.QMetaObject.connectSlotsByName(dialog_in) def cancelButton_clicked(self): print("cancelButton_clicked") def okButton_clicked(self): print("okButton_clicked") position=self.positionEdit.text() newRecord = self.model.record() newRecord.setValue("name", self.positionEdit.text()) if (self.model.insertRecord(self.model.rowCount(), newRecord)) : print("New record inserted") else: print("FAILED to insert new record") self.model.submitAll() self.model.select() print("position=" + position) self.close() class Dialog_add_new(QDialog, Ui_dialog_add_new): def __init__(self, parent=None, model=None): QDialog.__init__(self, parent) self.model = model self.setupUi(self) ########################################################## class positions_dialog(object): signalRefreshArticlesModel = QtCore.pyqtSignal() def setupUi(self, positions_dialog_in): self.setObjectName("positions_dialog_in") self.resize(500, 300) self.setWindowTitle("Positions - edit") self.setModal(True) self.layout = QtWidgets.QVBoxLayout(self) self.layout.setObjectName("layout") self.tableView = QtWidgets.QTableView(self) self.tableView.setObjectName("tableView") self.layout.addWidget(self.tableView) self.AddNewButton = QtWidgets.QPushButton(self) self.AddNewButton.setObjectName("AddNewButton") self.AddNewButton.setText("Add new position") self.layout.addWidget(self.AddNewButton) self.AddNewButton.clicked.connect(self.add_new_button_clicked) self.RefreshArticlesButton = QtWidgets.QPushButton(self) self.RefreshArticlesButton.setObjectName("RefreshArticlesButton") self.RefreshArticlesButton.setText("Refresh Articles") self.layout.addWidget(self.RefreshArticlesButton) self.RefreshArticlesButton.clicked.connect(self.refresh_articles_button_clicked) model = QSqlRelationalTableModel(self.tableView) model.setEditStrategy(QSqlTableModel.EditStrategy.OnFieldChange) model.setTable("positions") self.model = model self.tableView.setModel(model) if not model.select(): print(model.lastError()) def add_new_button_clicked(self): myDialog = Dialog_add_new(self, self.model) #myDialog = Positions() myDialog.exec() def refresh_articles_button_clicked(self): print("refresh_articles_button_clicked") self.signalRefreshArticlesModel.emit() class Positions(QDialog, positions_dialog): def __init__(self,parent=None): QDialog.__init__(self,parent) self.setupUi(self) ######################################################################################## ######################################################################################## from PyQt6.QtSql import QSqlDatabase, QSqlQuery from os.path import exists def add_article(q, name, position): q.addBindValue(name) q.addBindValue(position) q.exec() def add_posistion(q, name): q.addBindValue(name) #q.addBindValue(str(position)) q.exec() return q.lastInsertId() ARTICLES_SQL = """ create table IF NOT EXISTS articles(id integer primary key, name varchar, position integer) """ POSITIONS_SQL = """ create table IF NOT EXISTS positions(id integer primary key, name varchar) """ INSERT_ARTICLE_SQL = """ insert into articles(name, position) values(?, ?) """ INSERT_POSITION_SQL = """ insert into positions(name) values(?) """ def init_db(): """ init_db() Initializes the database. If tables "books" and "authors" are already in the database, do nothing. Return value: None or raises ValueError The error value is the QtSql error instance. """ def check(func, *args): if not func(*args): raise ValueError(func.__self__.lastError()) # returns false if db is not created file_exists = exists("inventory.db") print("file_exists=" + str(file_exists)) # add db driver db = QSqlDatabase.addDatabase("QSQLITE") # set db (or create it if not exists) db.setDatabaseName("inventory.db") # open db check(db.open) #add data only if db is just created (so file_exists returned 'false') if not file_exists: q = QSqlQuery() check(q.exec, ARTICLES_SQL) check(q.exec, POSITIONS_SQL) check(q.prepare, INSERT_POSITION_SQL) position1 = add_posistion(q, "Drawer 1") position2 = add_posistion(q, "Drawer 2") position3 = add_posistion(q, "Drawer 3") check(q.prepare,INSERT_ARTICLE_SQL) add_article(q, "Gendora key 15", position1) add_article(q, "Foundation and Empire", position1) add_article(q, "Second Foundation", position2) add_article(q, "Foundation's Edge", position1) add_article(q, "Foundation and Earth", position2) add_article(q, "Prelude to Foundation", position3) add_article(q, "Forward the Foundation", position3) add_article(q, "The Power and the Glory", position3) add_article(q, "The Third Man", position1) add_article(q, "Our Man in Havana", position3) add_article(q, "Guards! Guards!", position1) add_article(q, "Night Watch", position2) add_article(q, "Going Postal", position1) ######################################################################################## ####################################################################################### class myDelegate(QSqlRelationalDelegate): """Books delegate to rate the books""" def __init__(self, parent=None): print("myDelegate __init__") QSqlRelationalDelegate.__init__(self, parent) def createEditor(self, parent, option, index): # column of combo box 'position' positionColumn = 2 print("myDelegate.createEditor index.column()=" + str(index.column()) + " option=" + str(option) ) if index.column() == positionColumn: editor = QSqlRelationalDelegate.createEditor(self, parent, option, index) if isinstance(editor, QComboBox): editor.model().select() return editor else: return super(myDelegate, self).createEditor(parent, option, index) ################################################################################## if __name__ == "__main__": app = QApplication([]) import sys window = myWindow() window.resize(800, 600) window.show() sys.exit(app.exec())