Я использую QSqlRelationalTableModel с QSqlRelationalDelegate для простого приложения для редактирования базы данных.
Я хотел бы создать сигнал, когда пользователь изменяет значение (элемент) в записи с помощью редактора делегатов.
коды релизов: PyQt4 и python 3.5.6
здесь вы можете найти мой код.
Спасибо за нашу помощь.
библиотеки и константы
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
Класс реляционного делегата таблицы:
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)
Основная форма заявки:
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")
метод создания и добавления данных в мою базу данных:
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()