在QSqlTableModel中使用QSqlTableModel.OnFieldChange editStrategy时,如何知道数据库中的数据是否更新成功?

How to know if data updated successfully in database when using QSqlTableModel.OnFieldChange editStrategy in QSqlTableModel?

我正在使用 QSqlTableModel 和 QTableView 来表示我的数据库。我已成功将行插入到 tableModel:

 self.tableView = QtWidgets.QTableView(self.verticalLayoutWidget)
 self.table_model = QSqlTableModel(self.tableView, database)
 self.table_model.select()
 self.table_model.setEditStrategy(QSqlTableModel.OnFieldChange)

 self.table_model.insertRows(count, 1)

现在,我想在数据库中更新行之后添加一些其他功能。我正在使用:self.table_model.setEditStrategy(QSqlTableModel.OnFieldChange).
它会自动更新所有更改,所以我不知道在哪里处理数据库更新的 return 状态。

我试图处理这个信号:https://doc.qt.io/qt-5/qsqltablemodel.html#primeInsert。但是,我找不到任何资源或如何使用它的示例。

完整代码:

class Ui_MainWindow(object):
    # status new row in table
    newRow = False
    # status new copy row in table
    copyRow = False
    # Currently active persistent editors array
    persistentEditorArray = []

    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1049, 769)
        MainWindow.setWindowFlags(Qt.Window | Qt.FramelessWindowHint)

        MainWindow.setStyleSheet("background-color: rgb(106, 117, 202);")
        MainWindow.setObjectName("centralwidget")
        self.mdiArea = QtWidgets.QMdiArea(MainWindow)
        self.mdiArea.setGeometry(QtCore.QRect(20, 10, 1021, 721))
        self.mdiArea.setObjectName("mdiArea")
        self.mdiArea.setTabsMovable(False)
        self.subwindow = QtWidgets.QMdiSubWindow()
        self.subwindow.setObjectName("subwindow")
        self.subwindow.setGeometry(QtCore.QRect(0,0,self.mdiArea.width(),self.mdiArea.height()))
        self.subwindow.setWindowFlags(Qt.Window | Qt.FramelessWindowHint)
        self.mdiArea.addSubWindow( self.subwindow)
        self.verticalLayoutWidget = QtWidgets.QWidget(self.subwindow)
        self.verticalLayoutWidget.setGeometry(QtCore.QRect(0, 0, self.subwindow.width(), self.subwindow.height()))
        self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout.setObjectName("verticalLayout")
    
        self.createFrame()
        self.createTable()

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        MainWindow.setWindowTitle(_translate("Form", "Form"))

    def createTable(self):
        self.tableView = QtWidgets.QTableView(self.verticalLayoutWidget)
        self.tableView.setGeometry(QtCore.QRect(20, 150, 1011, 601))
        self.tableView.setObjectName("tableView")
        self.tableView.horizontalHeader().setSortIndicatorShown(True)
        self.tableView.verticalHeader().setVisible(False)
        self.tableView.horizontalHeader()
        self.tableView.setSelectionBehavior(QtWidgets.QTableView.SelectRows)
        self.tableView.setSelectionMode(QtWidgets.QTableView.SingleSelection)
        self.tableView.setFont(QFont('Gilroy', 12))
        self.tableView.clicked.connect(self.enableButtons)
        self.verticalLayout.addWidget(self.tableView)

        database = QSqlDatabase.addDatabase('QPSQL')
        database.setHostName('localhost')
        database.setPort(0002)
        database.setDatabaseName('example_db')
        database.setUserName('username')
        database.setPassword('password')
        ok = database.open()

        if not ok:
            logging.debug(database.lastError().text())
        # self.tableView.setRowCount(10)

        # database.commit()
        self.table_model = QSqlTableModel(self.tableView, database)
        table_name = 'example_table'
        self.table_model.setTable(table_name)

        self.table_model.setEditStrategy(QSqlTableModel.OnFieldChange)

        if not self.table_model.select():
            logging.debug(self.table_model.lastError().text())

        header_labels = ['id', 'Code', 'Name', 'Col1', 'Col3', 'Col2', 'Col4',
                         'Col5',
                         'Col6']
        for i, label in enumerate(header_labels):
            self.table_model.setHeaderData(i, QtCore.Qt.Horizontal, label, QtCore.Qt.DisplayRole)

            if i != 2:
                self.tableView.resizeColumnToContents(i)
        self.tableView.setModel(self.table_model)

        self.retranslateUiTable(self.tableView)
        for i, _ in enumerate(header_labels):
            if i != 2:
                self.tableView.resizeColumnToContents(i)
                self.tableView.horizontalHeader().setSectionResizeMode(i, QHeaderView.Fixed)
            else:
                self.tableView.horizontalHeader().setSectionResizeMode(i, QHeaderView.Stretch)


        self.tableView.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.tableView.setShowGrid(True)

    def enableButtons(self):
        if not self.table_model.isDirty():
            self.button_add.setEnabled(True)
            self.button_copy.setEnabled(True)
            for persistentEditor in self.persistentEditorArray:
                self.tableView.closePersistentEditor(persistentEditor)

    def disableButtons(self):
        self.button_add.setEnabled(False)
        self.button_copy.setEnabled(False)

    def addRow(self):
        count = self.table_model.rowCount(QModelIndex())
        self.table_model.insertRows(count, 1)
        self.tableView.scrollToBottom()
        self.table_model.setData(self.table_model.index(count, 0), count)
        self.newRow = True
        self.disableButtons()

    def copyRow(self):
        # if new Row adding process is not finished, revert all process stages and start copy Row process
        if self.newRow:
            self.table_model.revertAll()
        select = self.tableView.selectionModel()

        self.copyRow = True
        self.disableButtons()

        # if any row has not been selected, show a dialog with error message
        if not select.hasSelection():
            self.showDialog()
        else:
            rows = select.selectedRows()
            for row in rows:
                count = self.table_model.rowCount(QModelIndex())
                self.table_model.insertRow(count)
                self.table_model.setData(self.table_model.index(count, 0), count)
                for i in range(self.table_model.columnCount()):
                    row_data = row.sibling(row.row(), i).data()
                    if i < 2:
                        if i == 1:
                            self.table_model.setData(self.table_model.index(count, i), row_data[0:2])
                            self.tableView.openPersistentEditor(self.table_model.index(count, 1))
                            self.persistentEditorArray.append(self.table_model.index(count, 1))
                            self.tableView.openPersistentEditor(self.table_model.index(count, 2))
                            self.persistentEditorArray.append(self.table_model.index(count, 2))
                            self.tableView.openPersistentEditor(self.table_model.index(count, 3))
                            self.persistentEditorArray.append(self.table_model.index(count, 3))
                            self.tableView.openPersistentEditor(self.table_model.index(count, 4))
                            self.persistentEditorArray.append(self.table_model.index(count, 4))
                            self.tableView.openPersistentEditor(self.table_model.index(count, 5))
                            self.persistentEditorArray.append(self.table_model.index(count, 5))
                            self.tableView.openPersistentEditor(self.table_model.index(count, 6))
                            self.persistentEditorArray.append(self.table_model.index(count, 6))
                            self.tableView.openPersistentEditor(self.table_model.index(count, 7))
                            self.persistentEditorArray.append(self.table_model.index(count, 7))
                            self.tableView.openPersistentEditor(self.table_model.index(count, 8))
                            self.persistentEditorArray.append(self.table_model.index(count, 8))
                        continue
                    self.table_model.setData(self.table_model.index(count, i), row_data)

                self.tableView.scrollToBottom()

    def createFrame(self):

        self.frame = QtWidgets.QFrame(self.verticalLayoutWidget)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.frame.sizePolicy().hasHeightForWidth())
        self.frame.setSizePolicy(sizePolicy)
        self.frame.setMinimumSize(QtCore.QSize(self.verticalLayoutWidget.width(), 75))
        self.frame.setMaximumSize(QtCore.QSize(self.verticalLayoutWidget.width(), self.verticalLayoutWidget.height()))

        self.frame.setStyleSheet("background-color: rgb(255, 255, 255);")
        self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame.setObjectName("frame")
        self.frame.setStyleSheet(".QFrame{background-color: white; border: 1px; border-radius: 10px;}");

        self.verticalLayout.addWidget(self.frame, 0, QtCore.Qt.AlignHCenter)
        self.button_add = QPushButton(QIcon("../../static/img/036-add.png"), "", self.frame)
        self.button_add.setGeometry(QtCore.QRect(40, 15, 50, 50))
        self.button_add.setIconSize(self.button_add.size())
        self.button_add.clicked.connect(self.addRow)
        self.button_add.setFlat(True)

        self.button_copy = QPushButton(QIcon("../../static/img/025-copy.png"), "", self.frame)
        self.button_copy.setGeometry(QtCore.QRect(140, 15, 50, 50))
        self.button_copy.setIconSize(self.button_copy.size())
        self.button_copy.clicked.connect(self.copyRow)
        self.button_copy.setFlat(True)

    def showDialog(self):
        msg = QMessageBox()
        msg.setIcon(QMessageBox.Warning)
        msg.setText("No rows has been selected")
        msg.setInformativeText("Please select a row")
        msg.setWindowTitle("Error")
        msg.setStandardButtons(QMessageBox.Ok)

        retval = msg.exec_()
        print (retval)

    def retranslateUiTable(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setItemDelegate(CenterTextDelegate(Form))
        Form.setStyleSheet("QTableView {"
                               "selection-background-color : #7481EA;"
                               "font-weight: bolder;"
                               "font-style: normal;"
                               "background-color: white;"
                               "color: #193378;"
                           "}"
                           "QHeaderView { background-color: #E8ECF1;"
                           "color: #193378;"
                           " }"
                           "QScrollBar:vertical {"
                                "    border: 1px solid #999999;"
                                "    background:white;"
                                "    width:10px;    "
                                "    margin: 0px 0px 0px 0px;"
                            "}"
                            "QScrollBar::handle:vertical {"
                                "background-color: #6A75CA;"
                                "    min-height: 0px;"
                            "}"
                            "QScrollBar::add-line:vertical {"
                                "    background: qlineargradient(x1:0, y1:0, x2:1, y2:0,"
                                "    stop: 0 rgb(32, 47, 130), stop: 0.5 rgb(32, 47, 130),  stop:1 rgb(32, 47, 130));"
                                "    height: 0px;"
                                "    subcontrol-position: bottom;"
                                "    subcontrol-origin: margin;"
                            "}"
                            "QScrollBar::sub-line:vertical {"
                                "    background: qlineargradient(x1:0, y1:0, x2:1, y2:0,"
                                "    stop: 0  rgb(32, 47, 130), stop: 0.5 rgb(32, 47, 130),  stop:1 rgb(32, 47, 130));"
                                "    height: 0 px;"
                                "    subcontrol-position: top;"
                                "    subcontrol-origin: margin;"
                            "}"
                           "QLineEdit{"
                                "background-color:white;"
                                "border-style: inset;"
                                "border-width: 0.5px;"
                                "border-color: #6A75CA;"                                
                           "}")

        Form.hideColumn(0)

您可以覆盖 bool QSqlTableModel::submit() 槽,当用户停止编辑当前行时,它由项目委托调用。 source

bool SqlTableModel::submit()
{
    if (editStrategy() == QSqlTableModel::OnRowChange || editStrategy() == QSqlTableModel::OnFieldChange) {
        bool res = submitAll();
        // res is true on successfull query
        return res;
    }
    return true;
}