如何连接到QSqlDriver通知信号

How to connect to the QSqlDriver notification signal

如何绑定 SQLite 驱动程序通知信号以在 PyQt5 项目中包含通知源和负载,如 QT 的 C++ 文档中所示?据我所知,使用 driver[str].connect 语法重载信号将只接受一个参数。

connect(sqlDriver, QOverload<const QString &, QSqlDriver::NotificationSource, const QVariant &>::of(&QSqlDriver::notification),
    [=](const QString &name, QSqlDriver::NotificationSource source, const QVariant &payload){ /* ... */ });

可以在 https://doc.qt.io/qt-5/qsqldriver.html#notification-1

找到

最小示例:

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_())

一些相关链接:

您必须使用签名才能使用过载信号:

class Table(QtSql.QSqlTableModel):
    def __init__(self):
        super(Table, self).__init__()
        self.setTable("sportsmen")
        self.setEditStrategy(QtSql.QSqlTableModel.OnFieldChange)

        <b>self.database().driver().notification[
            str, QtSql.QSqlDriver.NotificationSource, "QVariant"
        ].connect(self.onNotification)</b>
        self.database().driver().subscribeToNotification("sportsmen")

    <b>@QtCore.pyqtSlot(str, QtSql.QSqlDriver.NotificationSource, "QVariant")</b>
    def onNotification(self, name, source, payload):
        print(name, source, payload)