【问题标题】:How to load data from SQLite database to tableview using the sqlite3 module如何使用 sqlite3 模块将数据从 SQLite 数据库加载到 tableview
【发布时间】:2022-01-21 13:39:30
【问题描述】:

我想使用模型视图控制器实现连接到数据库并从表中加载数据。到目前为止,所有示例都使用 PyQt5 的 QSqlDatabase 连接到数据库,并且表是由

model=QSqlTabelModel()
model.setTable("table_name")
table_view=QTableView()
table_view.setModel(model)
model.select()
.....

我认为model 能够从表中进行选择,因为它与数据库的连接使用QSqlDatabase。 我想做同样的事情,但使用sqlite3 模块连接到数据库。

【问题讨论】:

  • 这能回答你的问题吗? PyQt5 and persistent DB with QtSql
  • 不,这正是我目前所看到的。他们使用 QSqlDatabase,但我不想使用它。我想改用 sqlite3。
  • 你为什么不想使用它?
  • 我想知道这是否可能,我用 SQLite 开始了这个项目。我不想更改代码
  • 是的,这是可能的,但是您需要创建QAbstractItemModel 的子类并实现每个部分:模型结构、数据库连接、数据访问、异常/错误处理以及可能的一些缓存;如果还需要写入/修改支持,还必须实现数据写入(以及相关异常/错误处理)、布局更改、索引添加和删除等。

标签: python pyqt5 qtableview


【解决方案1】:

您可以使用 SQLite 内置的 Python 驱动程序,但是当您想要查看表时,您无法获得所有便利。如果你决定使用 sqlite3,那么你将不得不编写一些额外的代码来将数据从你的 sqlite3 光标推送到 QTableModel。

由于您已经致力于 PyQt5 库,您可以考虑学习如何使用 QtSQL。它具有支持许多知名数据库的优势,并且可以相对轻松地查看数据。

现在举个例子。首先创建数据库:

import sys
from PyQt5.QtSql import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

def createDB():
    db = QSqlDatabase.addDatabase('QSQLITE')
    db.setDatabaseName('test.db')
    
    # try to open the database
    if not db.open():
        raise Error("Could not open the database")


    query = QSqlQuery()

    # create a table
    query.exec_('''create table t1(
      id INTEGER PRIMARY KEY, fruit TEXT, inventory int);''')

    # populate the table
    query.exec_("insert into t1 (fruit, inventory) values('banana', 3);")
    query.exec_("insert into t1 (fruit, inventory) values('mango', 10);")
    query.exec_("insert into t1 (fruit, inventory) values('cherry', 55);")
    
    db.close()
    
if __name__ == '__main__':
   app = QApplication(sys.argv)
   createDB()

制作观众:

import sys
from PyQt5.QtSql import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *

class TableViewer(QMainWindow):
    def __init__(self):
        super().__init__()
        #createDB()
        
        self.db = QSqlDatabase.addDatabase('QSQLITE')
        self.db.setDatabaseName('test.db')
    
        # try to open the database
        if not self.db.open():
            raise Error("Could not open the database")

        # this will give you the whole table:
        self.model = QSqlTableModel(self, self.db)   
        self.model.setTable('t1')

        # if you don't need the whole table, you can try
        # using setSort() and setFilter() methods. if
        # those aren't satisfactory for you, you can 
        # replace the previous line with:
        #   query = QSqlQuery()
        #   query.exec_('select * from t1')
        #   self.model.setQuery(query)           

        self.model.select()

        self.tview = QTableView(self)
        self.tview.setModel(self.model)
        self.tview.resizeColumnsToContents()
        layout = QVBoxLayout()
        layout.addWidget(self.tview)
        
        widget = QWidget()
        widget.setLayout(layout)
        self.setCentralWidget(widget)

        self.show()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    tv = TableViewer()
    sys.exit(app.exec_())

【讨论】:

  • 这正是 cmets 中已经讨论过的内容(它还链接了一个已经回答了问题的答案):OP 不想使用 Qt 数据库系统,因为他们担心它会太在他们现有的 sqlite 实现中已经“完成”了很多工作,并希望找到另一种方法来“合并”Qt 项目模型,避免使用 QtSql。此外,文档不鼓励在 QSqlTableModel 上使用 setQuery
  • @musicamente,我明白为什么 OP 不想要 QtSQL,并且我意识到在 cmets 中讨论了利弊。但我认为如果发布者选择研究 QtSQL,发布一些示例代码很有用。很好地了解 setQuery。我无法从documentation 中弄清楚是否不鼓励使用此方法来隐藏 SQL 的复杂性或出于性能原因。我怀疑第一个。我经常在自己的生产代码中设置查询,没有遇到任何明显的问题。
  • 链接的问题已经有一些很好的示例代码,应该足够了(我将此问题标记为重复,但我错误地撤回了投票)。是的,文档没有说明为什么不应该使用它,也没有警告意外或不可靠的行为,这在理论上意味着它通常对于一般显示器使用是安全的。不幸的是,这对于完全使用是无效的:setTable() 通过准备索引和存储表名来正确“设置”表,这对于正确排序等某些功能至关重要;事实上,在你的 -> 上做 setSortingEnabled(True)
  • -> 代码导致标题显示排序箭头,但在单击部分时无效。调用setQuery() 也会使select() 无效(它返回False,因为selectStatement() 返回一个空字符串,因为它由于缺少表名而无法构造select 语句)。事实是,setTable() 已经自己调用了setQuery()(使用selectStatement())。因此,虽然对于一般的基本用法 setQuery() 可能 没问题,但不应该建议(尤其是对初学者),因为它可能会让人认为这是标准的接受用法,并且适用于任何查询。
  • 最好建议(并且通常使用)预定义的行为,并最终指定对于特定的选择查询可以使用 QSqlQueryModel 代替(记住默认情况下它是只读的,并且写支持必须通过实现setData()flags() 来添加)。如有疑问,我强烈建议仔细研究来源; woboq 提供了一个非常好的代码浏览器,它有一个非常有效的高亮系统,对学习和理解非常有帮助:code.woboq.org/qt5/qtbase/src/sql/models/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-09
  • 2012-08-14
  • 1970-01-01
  • 1970-01-01
  • 2017-03-21
  • 1970-01-01
相关资源
最近更新 更多