Reputation: 519
How can I bind the SQLite driver notification signal to include the notification source and payload in a PyQt5 project as seen in the C++ docs from QT? As far as I can see overloading the signal with the driver[str].connect syntax will only accept one argument.
connect(sqlDriver, QOverload<const QString &, QSqlDriver::NotificationSource, const QVariant &>::of(&QSqlDriver::notification),
[=](const QString &name, QSqlDriver::NotificationSource source, const QVariant &payload){ /* ... */ });
Can be found at https://doc.qt.io/qt-5/qsqldriver.html#notification-1
Minimal example:
import sys
from PyQt5 import QtSql, QtGui, QtWidgets
def createDB():
db = QtSql.QSqlDatabase.addDatabase('QSQLITE')
db.setDatabaseName(':memory:')
if not db.open():
print('could not open')
return False
query = QtSql.QSqlQuery()
query.exec_("create table sportsmen(id int primary key, "
"firstname varchar(20), lastname varchar(20))")
query.exec_("insert into sportsmen values(101, 'Roger', 'Federer')")
query.exec_("insert into sportsmen values(102, 'Christiano', 'Ronaldo')")
query.exec_("insert into sportsmen values(103, 'Ussain', 'Bolt')")
query.exec_("insert into sportsmen values(104, 'Sachin', 'Tendulkar')")
query.exec_("insert into sportsmen values(105, 'Saina', 'Nehwal')")
return db
class Table(QtSql.QSqlTableModel):
def __init__(self):
super(Table, self).__init__()
self.setTable('sportsmen')
self.setEditStrategy(QtSql.QSqlTableModel.OnFieldChange)
self.database().driver().subscribeToNotification('sportsmen')
self.database().driver().notification[str].connect(self.onNotification)
# signal = pyqtSignal([str], [QSqlDriver.NotificationSource], ['QVariant'])
# @pyqtSlot(str, int, str)
def onNotification(self, name, source=None, payout=None):
"""
Only sends the name of the signal, need to bind the full; name, source, paylad signal
"""
print(self.sender)
print(name, source, payout)
print('it worked')
def addrow():
print(model.rowCount())
record = model.record()
model.insertRecord(-1, record)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
db = createDB()
model = Table()
view = QtWidgets.QTableView()
view.setModel(model)
model.select()
dlg = QtWidgets.QDialog()
layout = QtWidgets.QVBoxLayout()
layout.addWidget(view)
button = QtWidgets.QPushButton("Add a row")
button.clicked.connect(addrow)
layout.addWidget(button)
btn1 = QtWidgets.QPushButton("del a row")
btn1.clicked.connect(lambda: model.removeRow(view.currentIndex().row()))
layout.addWidget(btn1)
dlg.setLayout(layout)
dlg.show()
sys.exit(app.exec_())
Some relevant links:
How to use Qt QSqlDriver::subscribeToNotification with SQLite3?
https://www.riverbankcomputing.com/static/Docs/PyQt5/signals_slots.html
Upvotes: 2
Views: 794
Reputation: 244093
You have to use the signature to use the overload signal:
class Table(QtSql.QSqlTableModel):
def __init__(self):
super(Table, self).__init__()
self.setTable("sportsmen")
self.setEditStrategy(QtSql.QSqlTableModel.OnFieldChange)
self.database().driver().notification[
str, QtSql.QSqlDriver.NotificationSource, "QVariant"
].connect(self.onNotification)
self.database().driver().subscribeToNotification("sportsmen")
@QtCore.pyqtSlot(str, QtSql.QSqlDriver.NotificationSource, "QVariant")
def onNotification(self, name, source, payload):
print(name, source, payload)
Upvotes: 2