我将PySide6与Python3.10结合使用,创建一个使用SQLite DB记录一些数据点的应用程序。
我在使用QtSql模块时遇到了困难,尤其是在QTableView QSqlTableModel交互以及创建/编辑/删除数据库中存在的记录的能力方面。
这是我试图实现的一个最低限度的重复性示例:
import logging
import sys
from PySide6.QtSql import QSqlDatabase, QSqlQuery, QSqlTableModel
from PySide6.QtWidgets import (
QApplication,
QHBoxLayout,
QMainWindow,
QPushButton,
QTableView,
QVBoxLayout,
QWidget,
)
class CustomSqlModel(QSqlTableModel):
def __init__(self, parent=None):
QSqlTableModel.__init__(self, parent=parent)
self.setTable("records")
self.setEditStrategy(QSqlTableModel.OnFieldChange)
self.select()
# Subclass QMainWindow to customize your application's main window
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
main_layout = QVBoxLayout()
buttons_layout = QHBoxLayout()
self.view = QTableView()
main_layout.addWidget(self.view)
main_layout.addLayout(buttons_layout)
self.add_button = QPushButton("+")
self.add_button.pressed.connect(self.add_action)
self.remove_button = QPushButton("-")
self.remove_button.pressed.connect(self.remove_action)
buttons_layout.addWidget(self.add_button)
buttons_layout.addWidget(self.remove_button)
widget = QWidget()
widget.setLayout(main_layout)
self.setCentralWidget(widget)
self.connect_to_db()
def add_action(self):
new_record = self.model.record()
new_record.setValue("point", 0)
self.model.insertRecord(self.model.rowCount(), new_record)
self.model.submitAll()
self.model.select()
def remove_action(self):
selected = self.view.currentIndex()
self.model.removeRow(selected.row())
self.model.submitAll()
self.model.select()
def connect_to_db(self):
self.database = QSqlDatabase.database()
if not self.database.isValid():
self.database = QSqlDatabase.addDatabase("QSQLITE")
self.database.setDatabaseName(f"test.db")
if not self.database.open():
logging.error("Failed to open db")
self.database = None
return
self.database.open()
if "records" not in self.database.tables():
query = QSqlQuery()
if not query.exec(
"""
CREATE TABLE IF NOT EXISTS records(
point REAL
)
"""
):
logging.error("Failed to query db")
if not query.exec(
"""
INSERT INTO records VALUES (0);
"""
):
logging.error("Failed to create initial data in db")
self.model = CustomSqlModel()
self.view.setModel(self.model)
app = QApplication(sys.argv)
window = MainWindow()
window.show()
app.exec()
当应用程序启动时,我会查找现有的SQLite DB并加载它。如果它不存在,我创建它并添加一个表
records
添加到它(一个单独的列,其中包含一个floting point值)。
界面中间的QTabLeVIEW控件显示加载的DB,并且可以直接从那里编辑记录。
小部件底部有两个按钮:
add_button
和
remove_button
,用于将一行添加到
记录
表,分别删除当前选定的表。
我的问题源于QTableView在使用我的UI创建/删除行时的行为:添加行一开始似乎工作正常,但删除一个新创建的行会删除所有行,而不仅仅是选定的行。此外,编辑其中一行,然后删除其中任何一行都不会导致任何删除,所有行都会获得与编辑行相同的值。
这个问题似乎与我的实现有关,因为如果我使用SQL编辑器(如DBeaver或DB Browser for Sqlite)编辑表,创建/编辑的行将正确显示在thr应用程序中。
我做错了什么?