【问题标题】:How to connect to the QSqlDriver notification signal如何连接到 QSqlDriver 通知信号
【发布时间】:2020-11-14 18:09:37
【问题描述】:

如何绑定 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_())

一些相关链接:

【问题讨论】:

    标签: python pyqt pyqt5


    【解决方案1】:

    你必须使用签名才能使用重载信号:

    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)

    【讨论】:

    • 太棒了,是否可以连接到 sqlite3_update_hook() 以获取有关创建、更新和删除事件的通知?
    • @DerekR。我一直在实现一个支持 QSQLite 驱动程序的额外功能的库,所以当我发布它时(几天后)我会通知你。
    • 听起来不错。我尝试订阅触发器,但似乎不起作用。
    • @DerekR.根据查看SQLiteplugin的源代码:github.com/qt/qtbase/blob/dev/src/plugins/sqldrivers/sqlite/…实现了Qt风格的通知信号,所以我认为没有必要暴露sqlite3_update_hook
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-23
    • 1970-01-01
    • 2020-09-20
    • 1970-01-01
    • 2013-02-06
    • 1970-01-01
    相关资源
    最近更新 更多