PyQt5和带有QtSql的持久数据库

时间:2018-07-12 13:14:16

标签: python-3.x pyqt5 qtsql

对PyQt5来说还很陌生,在设置示例应用程序时,我遇到了QtSql的问题。我发现的所有示例都显示了使用数据库连接的单个类,但是都没有显示如何在需要数据库连接的许多不同类上持久使用QtSql类。我的应用程序中几乎所有的MDI子窗口都需要与数据库的连接,但是当我建立连接时,会出现错误,指出该连接“重复”。我的问题是:

如果我有一个MDI应用程序,其中包含几个需要DB连接的对话框,那么如何持久地设置数据库连接,以便我所有的对话框都可以访问数据库?

1 个答案:

答案 0 :(得分:2)

如果您要连接到同一数据库,则不必创建多个连接,因为qt会docs来全局管理那些连接,所以只需创建一个连接:

  

QSqlDatabase QSqlDatabase :: addDatabase(const QString&type,const   QString&connectionName = QLatin1String(defaultConnection))

     

使用驱动程序类型将数据库添加到数据库连接列表中   连接名称connectionName。如果已经存在数据库   名为connectionName的连接,该连接将被删除。

     

数据库连接由connectionName引用。新   返回添加的数据库连接。

     

如果类型不可用或无法加载,则isValid()返回   错误。

     

如果未指定connectionName,则新连接将成为   应用程序的默认连接,以及随后的调用   没有连接名称参数的database()将返回   默认连接。如果此处提供了connectionName,请使用   database(connectionName)来检索连接。

     

警告:如果添加与现有名称相同的连接   连接,新连接将替换旧连接。如果你叫这个   在不指定connectionName(默认值)的情况下多次运行   连接将被替换。


示例:

.
├── connection.py
├── main.py
└── views.p

connection.py

from PyQt5 import QtWidgets, QtSql


def createConnection():
    db = QtSql.QSqlDatabase.addDatabase("QSQLITE")
    db.setDatabaseName(":memory:")
    if not db.open():
        QtWidgets.QMessageBox.critical(None, "Cannot open database",
                             "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.", QtWidgets.QMessageBox.Cancel)
        return False

    query = QtSql.QSqlQuery()
    query.exec_("""CREATE TABLE IF NOT EXISTS person (id int primary key, 
                                                     firstname VARCHAR(20), 
                                                    lastname VARCHAR(20))""")
    query.exec_("insert into person values(101, 'Danny', 'Young')")
    query.exec_("insert into person values(102, 'Christine', 'Holand')")
    query.exec_("insert into person values(103, 'Lars', 'Gordon')")
    query.exec_("insert into person values(104, 'Roberto', 'Robitaille')")
    query.exec_("insert into person values(105, 'Maria', 'Papadopoulos')")


    query.exec_("""CREATE TABLE IF NOT EXISTS  items (id INT primary key, 
                                       imagefile INT,
                                       itemtype varchar(20),
                                       description varchar(100))""");
    query.exec_("insert into items "
               "values(0, 0, 'Qt',"
               "'Qt is a full development framework with tools designed to "
               "streamline the creation of stunning applications and  "
               "amazing user interfaces for desktop, embedded and mobile "
               "platforms.')");
    query.exec_("insert into items "
               "values(1, 1, 'Qt Quick',"
               "'Qt Quick is a collection of techniques designed to help "
               "developers create intuitive, modern-looking, and fluid "
               "user interfaces using a CSS & JavaScript like language.')");
    query.exec_("insert into items "
               "values(2, 2, 'Qt Creator',"
               "'Qt Creator is a powerful cross-platform integrated "
               "development environment (IDE), including UI design tools "
               "and on-device debugging.')");
    query.exec_("insert into items "
               "values(3, 3, 'Qt Project',"
               "'The Qt Project governs the open source development of Qt, "
               "allowing anyone wanting to contribute to join the effort "
               "through a meritocratic structure of approvers and "
               "maintainers.')");
    return True

views.py

from PyQt5 import QtWidgets, QtSql

class PersonWidget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(PersonWidget, self).__init__(parent)
        lay = QtWidgets.QVBoxLayout(self)
        view = QtWidgets.QTableView()
        lay.addWidget(view)
        model = QtSql.QSqlTableModel(self)
        model.setTable("person")
        model.select()
        view.setModel(model)

class ItemsWidget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super(ItemsWidget, self).__init__(parent)
        lay = QtWidgets.QVBoxLayout(self)
        view = QtWidgets.QTableView()
        lay.addWidget(view)
        model = QtSql.QSqlTableModel(self)
        model.setTable("items")
        model.select()
        view.setModel(model)

main.py

from PyQt5 import QtWidgets, QtSql

from connection import createConnection
from views import PersonWidget, ItemsWidget


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        self.mdiarea = QtWidgets.QMdiArea()
        self.setCentralWidget(self.mdiarea)

        sub1 = QtWidgets.QMdiSubWindow()
        sub1.setWidget(PersonWidget())
        self.mdiarea.addSubWindow(sub1)
        sub1.show()

        sub2 = QtWidgets.QMdiSubWindow()
        sub2.setWidget(ItemsWidget())
        self.mdiarea.addSubWindow(sub2)
        sub2.show()

if __name__ == '__main__':
    import sys

    app = QtWidgets.QApplication(sys.argv)

    if not createConnection():
        sys.exit(-1)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

enter image description here

在前面的示例中,有一种createConnection()方法可以建立连接并在必要时创建表。并且使用数据库数据的视图未指明连接,因此使用默认连接,即在createConnection()中建立的连接。