如何在数据库中添加新条目时更新PyQt中的TableView?

时间:2016-11-21 02:49:16

标签: python sql database pyqt tableview

我正在尝试在PyQt Gui中更新我的TableView,以便每当新条目添加到QPSQL数据库时,它也会在Gui中的TableView中更新它。 目前,连接工作正常并且正确连接到数据库,并显示表中的内容,这只是一个电话簿,现在有一个名称,电话号码和地址列。问题是,如果我在Postgrese Sql数据库中插入一个新行,它将不会在TableView中更新,除非我关闭GUI并重新运行代码。 我只是想找到一种方法来更新我的TableView,这样如果有一些东西被添加到Postrgese SQL数据库中,它会自动执行它而不需要按钮或任何东西。感谢任何帮助,提前谢谢。

我也将展示我的代码的一部分。

class Ui_Dialog(object):
def setupUi(self, Dialog):
    Dialog.setObjectName(_fromUtf8("Dialog"))
    Dialog.resize(400, 300)
    self.buttonBox = QtGui.QDialogButtonBox(Dialog)
    self.buttonBox.setGeometry(QtCore.QRect(30, 240, 341, 32))
    self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
    self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
    self.buttonBox.setObjectName(_fromUtf8("buttonBox"))
    self.tableView = QtGui.QTableView(Dialog)
    self.tableView.setGeometry(QtCore.QRect(20, 50, 256, 192))
    self.tableView.setObjectName(_fromUtf8("tableView"))
###############################数据库连接
    db = QSqlDatabase.addDatabase("QPSQL")  # Database typed set to QPSQL for postgres use 
    db.setDatabaseName("postgres")          # This field should stay as postgres
    db.setUserName("postgres")              # This field should stay as postgres
    db.setPassword("pass")              # This field is for your personal password you used for the postgres install
    db.setHostName("localhost")             # This field should stay as localhost
    if not db.open():
      QtGui.QMessageBox.critical(None, QtGui.qApp.tr("Cannot open database"),
         QtGui.qApp.tr("Unable to establish a database connection.\n"
            "This example needs SQLite support. Please read "
            "the Qt SQL driver documentation for information "
            "how to build it.\n\n" "Click Cancel to exit."),
         QtGui.QMessageBox.Cancel)

      return False
    ok = db.open()
###############################将数据库表添加到主GUI中的表视图 #
    model = QSqlTableModel()
    query = QSqlQuery("SELECT * FROM PHONEBOOK", db)
    model.setEditStrategy(QSqlTableModel.OnFieldChange)
    model.setQuery(query)
    model.submitAll()

    self.tableView.setModel(model)
    self.tableView.show()
    model.select()

1 个答案:

答案 0 :(得分:1)

如果您能够在数据库中启用通知,那么只要您向表中添加内容,就可以使用QSqlDriver.subscribeToNotification来接收通知事件。如何启用通知取决于您管理数据库的方式,但首先要查看https://www.postgresql.org/docs/9.0/static/sql-notify.html

请注意,通知系统只是让我们的应用知道某些内容已发生变化。一旦你有一个连接到通知的插槽,你仍然需要决定如何处理它。每次收到通知时,您的应用都不一定会更新,取决于获取更新的费用。比如说,它每5秒最多可更新一次。

它看起来像这样:

db.exec("NOTIFY yourEventId")  # only this once for lifetime of database
db.driver().subscribeToNotification("yourEventId")
db.driver().notification.connect(self.yourSlot)

但有一件事,如果您的数据库将永远每秒更新一次(例如,因为它不断地读取硬件),您应该只轮询数据库(以常规时间间隔查询数据库以获取添加的记录)。当数据库更新之间的时间很长时,通知机制优于轮询。但是,如果更新频率(比如说每秒10次)比GUI表所需的刷新率(比如说每秒一次)更频繁,那么轮询可能会更好。

无论哪种方式,当数据库发生更改时,您的表都没有自动更新的方式,您至少必须添加更新表视图模型的代码,并且仅当您的应用确定数据库已更改时才会进行更新,这发生在轮询它或从中侦听修改事件(仅在postgresql AF​​AICT中可用)。