Signal for dataChanged with QSqlRelationalTableModel in pyqt

395 Views Asked by At

I'm using a QSqlRelationalTableModel with a QSqlRelationalDelegate for a simple database editing application.

I would like to create a signal when user modify a value (item) in a record with delegate editor.

codes releases: PyQt4 and python 3.5.6

here you can find my code. Thanks for our help.

libraries and constants

import os
import sys
import random

from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4.QtSql import *

MAC = True
try:
    from PyQt4.QtGui import qt_mac_set_native_menubar
except ImportError:
    MAC = False



#Columns View Rooms
ID = 0
ROOMNAME = 1
ROOMAREA = 2
TEMPLID = 3
TEMPLNAMEREL =4
TEMPLLIGHTGAINRATIOREL = 5
ROOMLIGHTGAINKW=6

Relational delegate class of table :

class RoomDelegate(QSqlRelationalDelegate):

    def __init__(self, parent=None):
        super(RoomDelegate, self).__init__(parent)

    def createEditor(self, parent, option, index):

        if index.column() in (-1,ROOMNAME): # Editables columns with text
            editor = QLineEdit(parent)
            return editor
        if index.column() in (-1,ROOMAREA): #Editables columns with doubles values
            doubSpinbox=QDoubleSpinBox(parent)
            doubSpinbox.setAlignment(Qt.AlignRight|Qt.AlignVCenter)
            return doubSpinbox

        if index.column()==TEMPLID: # Editables columns with ComboBox

            return QSqlRelationalDelegate.createEditor(self, parent,option, index)

        if index.column() in (TEMPLNAMEREL,TEMPLLIGHTGAINRATIOREL,ROOMLIGHTGAINKW): # no editables columns
            return # nothing because no ediatable

        else:
            return QSqlRelationalDelegate.createEditor(self, parent,option, index)



    def setEditorData(self, editor, index):
        text = index.model().data(index, Qt.DisplayRole) #instatiate value from courrent cell

        if index.column() in(-1, ROOMNAME): # Editables columns with text
            editor.setText(text)
        elif index.column() in(-1,ROOMAREA): #Editables columns with doubles values
            editor.setValue(text)
        else:
            QSqlRelationalDelegate.setEditorData(self, editor, index)


    def setModelData(self, editor, model, index):

        if index.column() in (ROOMNAME,TEMPLNAMEREL): #columns with text
            model.setData(index, editor.text())

        elif index.column() in (ROOMAREA,TEMPLLIGHTGAINRATIOREL,ROOMLIGHTGAINKW): #columns with doubles values
            model.setData(index, editor.value())
        else:
            QSqlRelationalDelegate.setModelData(self, editor, model,index)

Main form of application:

class MainForm(QDialog):

    def __init__(self):
        super(MainForm, self).__init__()

        #Model Rooms
        self.roomsModel = QSqlRelationalTableModel(self)
        self.roomsModel.setTable("rooms")
        self.roomsModel.setRelation(TEMPLID,
                QSqlRelation("templates", "id", "TemplCode"))

        self.roomsModel.setRelation(TEMPLNAMEREL,
                QSqlRelation("templates", "id", "TemplName"))

        self.roomsModel.setRelation(TEMPLLIGHTGAINRATIOREL,
                QSqlRelation("templates", "id", "TemplLightGainRatio"))

        self.roomsModel.setSort(ROOMNAME, Qt.AscendingOrder)
        self.roomsModel.setHeaderData(ID, Qt.Horizontal, "ID")
        self.roomsModel.setHeaderData(ROOMNAME, Qt.Horizontal,"RoomName")
        self.roomsModel.setHeaderData(ROOMAREA, Qt.Horizontal,"RoomArea [m²]")
        self.roomsModel.setHeaderData(TEMPLID, Qt.Horizontal,"Code Templ")
        self.roomsModel.setHeaderData(TEMPLNAMEREL, Qt.Horizontal,"Template Name")
        self.roomsModel.setHeaderData(TEMPLLIGHTGAINRATIOREL, Qt.Horizontal,"LightGainRatio [W/m²]")
        self.roomsModel.setHeaderData(ROOMLIGHTGAINKW, Qt.Horizontal,"LightGain [kW]")
        self.roomsModel.select()



        #View Rooms

        self.roomsView = QTableView()
        self.roomsView.setModel(self.roomsModel)
        self.roomsView.setItemDelegate(RoomDelegate(self))
        self.roomsView.setSelectionMode(QTableView.SingleSelection)
        self.roomsView.setSelectionBehavior(QTableView.SelectItems)
        self.roomsView.setColumnHidden(ID, False)
        self.roomsView.resizeColumnsToContents()
        self.roomsView.horizontalHeader().setStretchLastSection(True)


        #Tabs --------------
        tabs    = QTabWidget()

        # Create tabs
        tabTempl    = QWidget() 
        tabRoom = QWidget()
        # Resize width and height
        tabs.resize(250, 150)

        # Add tabs
        tabs.addTab(tabRoom,"Rooms")

        # Layout Rooms
        roomsLayout = QGridLayout()
        roomsLayout.addWidget(self.roomsView, 0,0)
        tabRoom.setLayout(roomsLayout)

        dataLayout = QGridLayout()
        dataLayout.addWidget(self.roomsView, 0,0)


        layout = QHBoxLayout()
        layout.addWidget(tabs, 1)

        self.setLayout(layout)


        self.setMinimumWidth(650)
        self.setWindowTitle("Mini Database")

method for create and add data into my database :

def createDataMiniDataBase():

    # delete existing tables  (Drop)
    print("Dropping tables...")
    query = QSqlQuery()
    query.exec_("DROP TABLE templates")
    query.exec_("DROP TABLE rooms")

    QApplication.processEvents()

    print("Creating tables...")

    query.exec_("""CREATE TABLE templates (
                id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL,
                TemplCode VARCHAR(20) NOT NULL UNIQUE,
                TemplName VARCHAR(20) NOT NULL UNIQUE,
                TemplLightGainRatio REAL NOT NULL)""")

    query.exec_("""CREATE TABLE rooms (
                id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL,
                RoomName VARCHAR(20) NOT NULL,
                RoomArea REAL NOT NULL,
                TemplId INTEGER NOT NULL,
                TemplName INTEGER NOT NULL,
                TemplLightGainRatio INTEGER NOT NULL,
                RoomLightGainkW REAL NOT NULL,
                FOREIGN KEY (TemplId) REFERENCES templates,
                FOREIGN KEY (TemplName) REFERENCES templates,
                FOREIGN KEY (TemplLightGainRatio) REFERENCES templates)""")


    QApplication.processEvents()


    print("Populating tables...")

    #Default Template:
    DefTempId ='0'
    DefTempTemplCode='def'
    DefTempTemplName='Default'
    DefTempTemplLightGainRatio='0'


    # templates table -----------------
    query.prepare("INSERT INTO templates (id,TemplCode, TemplName,TemplLightGainRatio) "
                  "VALUES (:id,:TemplCode, :TemplName,:TemplLightGainRatio)")

    query.bindValue(":id", DefTempId)
    query.bindValue(":TemplCode", DefTempTemplCode)
    query.bindValue(":TemplName", DefTempTemplName)
    query.bindValue(":TemplLightGainRatio", DefTempTemplLightGainRatio)

    query.exec_()

    query.exec_("INSERT INTO templates (TemplCode, TemplName,TemplLightGainRatio) "
                "VALUES ('CH01', 'NameTemp 01','15')")
    query.exec_("INSERT INTO templates (TemplCode, TemplName,TemplLightGainRatio) "
                "VALUES ('CH02', 'NameTemp 02','25')")


    #rooms table --------------------------
    query.prepare("INSERT INTO rooms (RoomName, RoomArea, TemplId,TemplName,TemplLightGainRatio,RoomLightGainkW) "
                  "VALUES (:RoomName, :RoomArea, :TemplId,:TemplName,:TemplLightGainRatio, :RoomLightGainkW)")



    nb=0
    for i in range(10):
        nb+=1
        RoomName="Room"+" "+str(nb)
        RoomArea=random.uniform(0, 150)
        RoomArea=round(RoomArea,2)

        query.bindValue(":RoomName", RoomName)
        query.bindValue(":RoomArea", RoomArea)
        query.bindValue(":TemplId", DefTempId)
        query.bindValue(":TemplName", DefTempId)
        query.bindValue(":TemplLightGainRatio", DefTempId)

        query.bindValue(":RoomLightGainkW", 0)
        query.exec_()       



def main():

    # Create Mini Data Base File

    app = QApplication(sys.argv)

    filename = os.path.join(os.path.dirname(__file__), "MiniDataBase.db")
    create = not QFile.exists(filename)
    db = QSqlDatabase.addDatabase("QSQLITE")
    db.setDatabaseName(filename)
    if not db.open():
        QMessageBox.warning(None, "MiniDataBase Manager",
            "Database Error: {}".format(db.lastError().text()))
        sys.exit(1)


    # Populate Mini Data Base File
    createDataMiniDataBase()

    form = MainForm()
    form.show()

    app.exec_()

main()
0

There are 0 best solutions below