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

QTableView搭配QSqlRelationalTableModel时行消失原因排查

QSqlRelationalTableModel设置OnFieldChange后编辑单元格整行消失的解决方法

当使用QSqlRelationalTableModel并将编辑策略设置为OnFieldChange时,修改单元格值后整行会消失,且无法再修改该行其他单元格。即使尝试添加外键、调整编辑策略,问题依然存在。

编辑前效果:
编辑前
编辑后效果:
编辑后

问题根源

  1. 数据库表缺少主键:QSqlRelationalTableModel依赖主键唯一标识和追踪数据行,无主键时模型无法在提交修改后匹配原行,导致行从视图中消失。
  2. 模型初始化顺序错误:先调用select()再设置关联和编辑策略,会导致模型状态不一致,关联无法正确生效。
  3. 使用数字常量设置编辑策略:直接用0代替枚举值,代码可读性差且易出错。

解决方案

1. 修改数据库表结构,添加主键

更新建表语句,为两个表添加主键(仅需执行一次):

import sqlite3

with sqlite3.connect('db.db') as con:
    cur = con.cursor()
    # 为tab表添加自增主键id
    cur.execute('CREATE TABLE IF NOT EXISTS tab (id INTEGER PRIMARY KEY AUTOINCREMENT, "static_col", "relation_col1", "relation_col2")')
    # 将relation表的rel字段设为主键
    cur.execute('CREATE TABLE IF NOT EXISTS relation (rel INTEGER PRIMARY KEY)')
    cur.execute('INSERT INTO tab(static_col) VALUES ("Lorem"), ("ipsum"), ("dolor"),("sit")')
    cur.execute('INSERT INTO relation(rel) VALUES (69), (322)')

2. 调整模型初始化顺序并修正配置

修改模型初始化代码,确保先完成配置再加载数据,同时使用枚举值设置编辑策略:

from ui_ui import Ui_Form
from PyQt5 import QtWidgets
from PyQt5.QtSql import QSqlRelationalTableModel, QSqlDatabase, QSqlRelationalDelegate, QSqlRelation, QSqlTableModel
import sys

db = QSqlDatabase.addDatabase('QSQLITE')
db.setDatabaseName('db.db')
db.open()

class MainWindow(QtWidgets.QWidget, Ui_Form):
    def __init__(self):
        QtWidgets.QWidget.__init__(self)
        self.setupUi(self)

        table_model = QSqlRelationalTableModel(db=db)
        table_model.setTable('tab')
        # 先设置关联(添加主键后,relation_col1的列索引变为2)
        table_model.setRelation(2, QSqlRelation('relation', 'rel', 'rel'))
        # 使用枚举值设置编辑策略,可读性更强
        table_model.setEditStrategy(QSqlTableModel.OnFieldChange)
        # 最后执行select加载数据
        table_model.select()
        
        self.tableView_1.setModel(table_model)
        delegate = QSqlRelationalDelegate(self.tableView_1)
        self.tableView_1.setItemDelegateForColumn(2, delegate)

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    main = MainWindow()
    main.show()
    sys.exit(app.exec_())

关键说明

  • 主键的必要性:SQLite和Qt的SQL模型要求表必须有主键,否则无法正确处理行的修改、删除等操作,尤其是即时提交的编辑策略。
  • 初始化顺序:必须先完成模型的所有配置(表、关联、编辑策略),再调用select(),确保模型加载数据时使用正确的配置。
  • 列索引修正:添加主键id后,原relation_col1的列索引从1变为2,需同步修改关联和代理的列参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 13:35:41