PyQt & QtSql 数据库 - 自定义连接和 QSqlTableModel 的问题

Posted

技术标签:

【中文标题】PyQt & QtSql 数据库 - 自定义连接和 QSqlTableModel 的问题【英文标题】:PyQt & QtSql databases - problems with custom connection and QSqlTableModel 【发布时间】:2021-05-18 08:58:59 【问题描述】:

我正在尝试制作一个表格来查看数据库,作为更大项目的一部分。整个项目使用了许多数据库和连接,所以我必须使用自定义连接名称来管理它们。

问题是,尽管事实上,数据库正在打开并且文件似乎已正确生成,但我无法在 QSqlTableModel 表中查看它,文档并没有太大帮助。

这里是脚本:

database.py

from PyQt5.QtWidgets import QMessageBox
from PyQt5.QtSql import QSqlDatabase, QSqlQuery
from PyQt5 import QtSql


def createConnection():
    """Create and open a database connection."""
    connection = QtSql.QSqlDatabase.addDatabase("QSQLITE", "conkon")
    connection.setDatabaseName("contacts.sqlite")
    query = QtSql.QSqlQuery(connection)
    if connection.open():
        query.exec(
           """
           CREATE TABLE IF NOT EXISTS contacts (
               short VARCHAR(40) NOT NULL,
               fullname VARCHAR(50) NOT NULL,
               NIP VARCHAR(50),
               postcode VARCHAR(50) NOT NULL,
               city VARCHAR(50) NOT NULL,
               street VARCHAR(50) NOT NULL,
               phone VARCHAR(50),
               email VARCHAR(40),
               discount INTEGER,
               comment VARCHAR(40)
           )
           """
       )

model.py

from PyQt5.QtCore import Qt
from PyQt5.QtSql import QSqlTableModel
from PyQt5 import QtWidgets, QtSql

class ContactsModel():
    def __init__(self):
        self.model = self._createModel()

    @staticmethod
    def _createModel():
        tableModel = QtSql.QSqlTableModel(None, QtSql.QSqlDatabase.database("contacts.sqlite"))
        tableModel.setTable("contacts")
        tableModel.setEditStrategy(QSqlTableModel.OnFieldChange)
        tableModel.select()
        headers = ("Skrót", "Pełna Nazwa", "NIP", "Kod pocztowy", "Miejscowość", "Ulica", "Telefon", "Email", "Rabat", "Komentarz" )
        for columnIndex, header in enumerate(headers):
            tableModel.setHeaderData(columnIndex, Qt.Horizontal, header)
            return tableModel

窗口声明表单views.py的片段

    """Main Window."""

    def __init__(self):
        """Initializer."""
        super().__init__()
        self.setWindowTitle("MOJManager")
        self.resize(1000, 250)
        self.centralWidget = QWidget()
        self.setCentralWidget(self.centralWidget)
        self.layout = QHBoxLayout()
        self.centralWidget.setLayout(self.layout)
        self.contactsModel = ContactsModel()
        self.setupUI()

   def setupUI(self):
        """Setup the main window's GUI."""
        # Create the table view widget
        self.table = QTableView()
        self.table.setModel(self.contactsModel.model)
        self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
        self.table.resizeColumnsToContents()
        # Create buttons
        self.addButton = QPushButton("Dodaj")
        self.addButton.clicked.connect(self.openAddDialog)
        self.deleteButton = QPushButton("Usuń")
        self.deleteButton.clicked.connect(self.deleteContact)
        self.clearAllButton = QPushButton("Wyczyść wszystko")
        self.clearAllButton.clicked.connect(self.clearContacts)
        # Lay out the GUI
        layout = QVBoxLayout()
        layout.addWidget(self.addButton)
        layout.addWidget(self.deleteButton)
        layout.addStretch()
        layout.addWidget(self.clearAllButton)
        self.layout.addWidget(self.table)
        self.layout.addLayout(layout)

ma​​in.py


import sys

from PyQt5.QtWidgets import QApplication

from .database import createConnection
from .views import WindowKontakty


def mainKont():
    """RP Contacts main function."""
    app = QApplication(sys.argv)
   # Connect to the database before creating any window
    createConnection()
    # Create the main window if the connection succeeded
    winMag = WindowKontakty()
    winMag.show()
    sys.exit(app.exec_())
    return winMag

问题是,任何地方都没有显示错误(,数据库似乎已打开。我无法从表视图中填充它,只能使用查询。我发现问题可能与此数据库连接有关,但我不知道在哪里。谁能帮忙看看?

编辑:我在 views.py 上添加了带有 setModel() 的代码片段

【问题讨论】:

你把模型放在桌子上的什么地方?而 for 循环中的 return 似乎有错误的缩进。 这里在模型中的初始化函数 self.model = self._createModel() 只是创建模型。在某些时候,您应该有一个 QTableView 并使用该模型调用setModel()。如果你不这样做,视图怎么会知道它应该显示的数据? 我已经编辑了缺少代码片段的帖子。它适用于默认数据库/连接。 @LGusti 请提供minimal reproducible example 【参考方案1】:

问题解决了,它在于 tableModel.setTable("contacts") 方法,它应该通过连接来解决,而不是数据库名。更改为时唤醒

tableModel.setTable("conkon")

更改后,表格可以正常生成。

【讨论】:

对不起,什么?!正在生成什么表?

以上是关于PyQt & QtSql 数据库 - 自定义连接和 QSqlTableModel 的问题的主要内容,如果未能解决你的问题,请参考以下文章

在 Qtsql PyQT4 中添加列名和值作为变量

如何包含 qtsql 模块?

pyqt5最简单操作数据库

PyQt - 重新实现 QSqlTableModel 的数据方法的麻烦

PyQt5 批量删除 Excel 重复数据,多个文件自定义重复项一键删除...

PyQt5 GUI Programming With Python 3.6