Ich habe eine QSqlDatabase (in einer eigenen Klasse, unten MySQLite an QSqlRelationalTableModel gekoppelt. Das wiederum kommuniziert über ein QAbstractItemView Klasse mit einem QTableView. Im eigentlichen Plan sollen dann Eingaben über eine Dialogbox (Im Beispiel vereinfacht ohne Dialog) eingegeben und an die QSqlDatabase weitergegeben werden. Die Anzeige im TableView wird allerdings nicht aktualisiert und ich finde keinen Hinweis darauf, wie ich das über die zwei Models realisieren soll, dass sich das TableView nach jeder Eingabe aktuallisert. Muss ich noch irgendwo ein insertRow() implementieren, und wenn ja in welchem Model? Hat da jemand den entsprechenden Hinweis?
Gespeichert werden die Daten. Oder ist der strukturelle/programmatische Ansatz hier schon verkehrt? (Ist mein erster Versuch mit QSql)
Folgend ein Beispiel:
Code: Alles auswählen
import sys
from PyQt5.QtWidgets import (QWidget, QTableView, QMainWindow, QApplication, QAbstractItemView, QPushButton, QVBoxLayout,
QSpinBox, QLineEdit)
from PyQt5.QtCore import QAbstractTableModel, pyqtSlot, pyqtSignal, Qt
from PyQt5.QtSql import QSqlRelationalTableModel, QSqlDatabase, QSqlQuery, QSql
class MyViewWidget(QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.mysqlite = MySQLite()
self.create_view()
def create_view(self):
self.model_sql = QSqlRelationalTableModel(self, self.mysqlite.databse)
self.model_sql.setTable("Points")
self.model_sql.select()
self.model = MyModel(self.model_sql)
self.table_view = QTableView()
self.table_view.setModel(self.model)
self.table_view.setSelectionMode(QAbstractItemView.SingleSelection)
self.table_view.setSelectionBehavior(QAbstractItemView.SelectRows)
self.spin_box = QSpinBox()
self.line_edit = QLineEdit()
self.button = QPushButton("Add")
self.button.clicked.connect(self.on_push_button)
layout = QVBoxLayout()
layout.addWidget(self.table_view)
layout.addWidget(self.spin_box)
layout.addWidget(self.line_edit)
layout.addWidget(self.button)
central_widget = QWidget()
central_widget.setLayout(layout)
self.setCentralWidget(central_widget)
@pyqtSlot()
def on_push_button(self):
data = dict(id=self.spin_box.text(), name=self.line_edit.text())
self.mysqlite.insert_item(data)
def closeEvent(self, event):
self.mysqlite.save()
self.mysqlite.close()
event.accept()
class MyModel(QAbstractTableModel):
def __init__(self, model):
super().__init__(model)
self._model_sql = model
def rowCount(self, index=None):
return self._model_sql.rowCount()
def columnCount(self, index=None):
return self._model_sql.columnCount()
def headerData(self, section, orientation, role):
if role == Qt.DisplayRole and orientation == Qt.Horizontal:
if section == 0:
return "ID"
elif section == 1:
return "Name"
def data(self, index, role=Qt.DisplayRole):
if not index.isValid():
return None
elif role == Qt.DisplayRole:
column = index.column()
if column == 0:
return self._model_sql.record(index.row()).value(column)
elif column == 1:
value = self._model_sql.record(index.row()).value(column)
return f"RIP {value}"
else:
return None
return None
class MySQLite:
def __init__(self, parent=None):
super().__init__()
self.open_sql_database()
def open_sql_database(self):
self.database = QSqlDatabase.addDatabase("QSQLITE")
self.database.setDatabaseName("test_sql.slite")
self.database.open()
if len(self.database.tables()) == 0:
self.create_table()
def create_table(self):
sql = QSqlQuery(self.database)
sql.exec("""
CREATE TABLE Points (
id INTEGER PRIMARY KEY UNIQUE NOT NULL,
name TEXT NOT NULL
)
""")
def insert_item(self, data):
print(data)
query = QSqlQuery(self.databse)
query.prepare("INSERT INTO Points (id, name) VALUES(?, ?)")
query.bindValue(0, data["id"], QSql.In)
query.bindValue(1, data["name"], QSql.In)
return query.exec()
@property
def databse(self):
return self.database
def save(self):
self.database.commit()
def close(self):
self.database.close()
def main(argv):
app = QApplication(argv)
window = MyViewWidget()
window.show()
window.resize(500, 300)
sys.exit(app.exec_())
if __name__ == "__main__":
main(sys.argv)