首页 > 解决方案 > 使用 insertRecord 时如何正确处理 QSqlTableModel 中的错误

问题描述

我到处寻找,但找不到解决问题的方法。我要做的就是通过表单将新记录插入数据库,如果成功插入记录[行编辑中的有效条目],请清除表单;否则抛出错误。下面请看一个最小的代码。为了给出一些上下文,表中的“状态”字段有一个限制,只能接受 2 个字符[状态缩写]。在插入方法中,if-else 语句会导致以下行为。如果我插入一条有效记录,[John, NY] 记录就会成功插入;但是 QMessageBox 也出现在屏幕上,但没有显示任何错误。此外,表格(行编辑)不会被清除。如果我尝试插入无效记录 [John, New York],QMessageBox 出现检查违规错误,并且行编辑中的条目保留在那里;但是,当我更正状态条目(将纽约更改为纽约)并再次点击按钮时,我仍然在屏幕上收到相同的错误消息,但在后台记录被插入到表中;表格也没有被清除。然后我尝试使用 try-except-else 块,但也没有用。在有效条目的情况下,它工作正常。但是,如果我在状态行编辑中输入无效值 QMessageBox 不会出现;表格也被清除。不知道我做错了什么。表格也没有被清除。然后我尝试使用 try-except-else 块,但也没有用。在有效条目的情况下,它工作正常。但是,如果我在状态行编辑中输入无效值 QMessageBox 不会出现;表格也被清除。不知道我做错了什么。表格也没有被清除。然后我尝试使用 try-except-else 块,但也没有用。在有效条目的情况下,它工作正常。但是,如果我在状态行编辑中输入无效值 QMessageBox 不会出现;表格也被清除。不知道我做错了什么。

import sys
from PyQt5 import QtWidgets as qtw
import PyQt5.QtSql as qpsql

class MainWindow(qtw.QMainWindow):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.layout = qtw.QVBoxLayout()
        self.first_name_line_edit = qtw.QLineEdit('first_name')
        self.state_line_edit = qtw.QLineEdit('state')
        self.layout.addWidget(self.first_name_line_edit)
        self.layout.addWidget(self.state_line_edit)
        self.insert_button = qtw.QPushButton('Insert')
        self.insert_button.clicked.connect(self.insert)
        self.layout.addWidget(self.insert_button)

        self.model = qpsql.QSqlTableModel(db = db_)
        self.table = qtw.QTableView()
        self.table.setModel(self.model)

        self.mapper = qtw.QDataWidgetMapper()
        self.mapper.setModel(self.model)
        self.mapper.setSubmitPolicy(qtw.QDataWidgetMapper.ManualSubmit)
        self.model.setTable('table')
        
        self.mapper.addMapping(self.first_name_line_edit, self.model.fieldIndex('first_name'))
        self.mapper.addMapping(self.state_line_edit, self.model.fieldIndex('state'))
        self.model.select()

        self.layout.addWidget(self.table)

        self.widget = qtw.QWidget()
        self.widget.setLayout(self.layout)
        self.setCentralWidget(self.widget)

    def clear_(self):
        self.first_name_line_edit.clear()
        self.state_line_edit.clear()

    def insert(self):

        record = self.model.record()
        record.setValue('first_name', self.first_name_line_edit.text())
        record.setValue('state', self.state_line_edit.text())

        # 1. Record gets inserted;QMessageBox pops up without any error printed; Line edits don't clear.
        if self.model.insertRecord(-1, record):
             self.model.submitAll()
             self.clear_()
        else:
             qtw.QMessageBox.critical(None, "Error", self.model.lastError().text())

        # 2. QMessageBox doesn't appear; Line Edits get clear;
        # try:
        #     self.model.insertRecord(-1, record)
        #     self.model.submitAll()
        # except Exception:
        #     qtw.QMessageBox.critical(None, "Error", self.model.lastError().text())
        # else:
        #     self.clear_()
if __name__ == '__main__':
    app = qtw.QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

标签: pythonpyqtqsqltablemodel

解决方案


推荐阅读