You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PySide6 QTableView排序后删除数据库记录错误问题求助

解决QTableView排序后删除对应数据库记录的问题

核心问题是:QTableView的行索引是排序后视图的索引,并非数据库原始表的行索引,不能直接用视图行索引去操作数据库原始行。必须通过QtSql模型的索引映射来定位正确的数据库记录。

正确实现步骤

  1. 获取视图选中的模型索引:从QTableView获取选中的QModelIndex,该索引已关联到排序后的模型行。
  2. 通过模型删除对应记录:利用模型的removeRow()方法,传入选中索引的行号,模型会自动映射到数据库中对应的真实记录。
  3. (可选)处理多行删除:如果支持多行删除,需从后往前删除,避免因行索引变动导致漏删或错删。

示例代码

from PySide6.QtWidgets import QTableView, QPushButton, QWidget, QVBoxLayout
from PySide6.QtSql import QSqlRelationalTableModel, QSqlDatabase
from PySide6.QtCore import Qt

class MainWidget(QWidget):
    def __init__(self):
        super().__init__()
        self.init_ui()
        self.init_db_and_model()

    def init_ui(self):
        self.table_view = QTableView()
        self.delete_btn = QPushButton("删除选中记录")
        self.delete_btn.clicked.connect(self.delete_selected_records)

        layout = QVBoxLayout()
        layout.addWidget(self.table_view)
        layout.addWidget(self.delete_btn)
        self.setLayout(layout)

    def init_db_and_model(self):
        # 初始化SQLite数据库
        db = QSqlDatabase.addDatabase("QSQLITE")
        db.setDatabaseName("test.db")
        if not db.open():
            print("数据库打开失败")
            return

        # 初始化模型
        self.model = QSqlRelationalTableModel(self, db)
        self.model.setTable("your_table_name")  # 替换为你的表名
        self.model.setEditStrategy(QSqlRelationalTableModel.OnManualSubmit)
        self.model.select()

        # 设置排序(示例:按日期列排序,假设日期列索引为2)
        self.model.setSort(2, Qt.DescendingOrder)
        self.model.select()

        # 关联模型到视图,启用排序
        self.table_view.setModel(self.model)
        self.table_view.setSortingEnabled(True)

    def delete_selected_records(self):
        # 获取选中的所有索引
        selected_indexes = self.table_view.selectedIndexes()
        if not selected_indexes:
            return

        # 去重,只保留每行的第一个索引(避免同一行多列选中重复处理)
        selected_rows = set()
        for index in selected_indexes:
            selected_rows.add(index.row())

        # 从后往前删除,防止行索引变动导致错误
        for row in sorted(selected_rows, reverse=True):
            # 直接通过模型删除对应行,模型会自动映射到数据库正确记录
            self.model.removeRow(row)

        # 提交更改到数据库(如果用了OnManualSubmit策略)
        self.model.submitAll()

关键说明

  • 模型的编辑策略:如果使用OnManualSubmit,需要调用submitAll()将删除操作提交到数据库;若使用OnFieldChange或OnRowChange,删除会自动提交。
  • 索引映射:QSqlRelationalTableModel排序后,模型内部已维护了视图行与数据库记录的映射关系,直接调用removeRow(row)即可删除视图选中行对应的真实数据库记录,无需手动关联数据库原始行索引。
  • 多行删除顺序:从后往前删除是因为删除前面的行后,后面的行索引会前移,如果从前往后删,会导致后续行的索引不准确。

内容的提问来源于stack exchange,提问作者Dag

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 02:18:09