Python 2.7 PyQt4/QTableView:“;运行时错误“;执行撤消时&;使用QUndoStack类重做操作

Python 2.7 PyQt4/QTableView:“;运行时错误“;执行撤消时&;使用QUndoStack类重做操作,python-2.7,pyqt4,Python 2.7,Pyqt4,我已经使用PyQt4中的QUndoStack类为QTableView编写了Undo&Redo操作代码 撤销操作工作正常;但是当我执行重做操作时,我得到了“RuntimeError:调用Python对象时超过了最大递归深度”。 我使用QTableView的按下&数据更改信号从模型中检索文本 下面是代码示例 from PyQt4.QtGui import * from PyQt4.QtCore import * from PyQt4.QtSql import * import os import s

我已经使用PyQt4中的QUndoStack类为QTableView编写了Undo&Redo操作代码

撤销操作工作正常;但是当我执行重做操作时,我得到了“RuntimeError:调用Python对象时超过了最大递归深度”。

我使用QTableView的
按下
&
数据更改
信号从模型中检索文本

下面是代码示例

from PyQt4.QtGui import *
from PyQt4.QtCore import *
from PyQt4.QtSql import *
import os
import sys
import random

# SQL Query:---------------------------------------------------------------------------------------------

def StudentQuery():
    StudentQuery = QSqlQuery()
    StudentQuery.exec_("DROP TABLE STUDENTS")
    StudentQuery.exec_("""CREATE TABLE STUDENTS (
                    s1 REAL NULL,
                    s2 REAL NULL,
                    s3 REAL NULL)""")
    Students = ("STD1", "STD2", "STD3")
    StudentQuery.prepare("INSERT INTO STUDENTS (s1, s2, s3) VALUES (?, ?, ?)")
    for Student in Students:
        s1 = random.randint(0, 25)
        s2 = random.randint(0, 25)
        s3 = random.randint(0, 25)

    StudentQuery.addBindValue(QVariant(s1))
    StudentQuery.addBindValue(QVariant(s2))
    StudentQuery.addBindValue(QVariant(s3))
    StudentQuery.exec_()

QApplication.processEvents()

# Ui Dialog:------------------------------------------------------------------------------------------------

class Ui_Student(QDialog):

    def __init__(self, parent=None):
        super(Ui_Student, self).__init__(parent)

        self.setFixedSize(340, 170)
        self.setWindowTitle("STUDENT")

        self.model = QSqlTableModel(self)
        self.model.setTable("STUDENTS")
        self.model.setEditStrategy(QSqlTableModel.OnManualSubmit)
        self.model.select()

        self.view = QTableView(self)
        self.view.setGeometry(QRect(10, 10, 320, 120))
        self.view.setSelectionBehavior(QAbstractItemView.SelectItems)
        self.view.setFocusPolicy(Qt.StrongFocus)
        self.view.setModel(self.model)

        self.view.installEventFilter(self)

        QSqlDatabase.database().commit()

    # Button Box:---------------------------------------------------------------------------------------------------

        self.buttonBox = QDialogButtonBox(self)
        self.buttonBox.setGeometry(QRect(118, 127, 100, 45))
        self.buttonBox.setOrientation(Qt.Horizontal)
        self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel | QDialogButtonBox.Ok)

    # SIGNAL & SLOT: -----------------------------------------------------------------------------------------------

        QObject.connect(self.buttonBox, SIGNAL("accepted()"), self.accept)
        QObject.connect(self.buttonBox, SIGNAL("rejected()"), self.reject)

    # Code For Undo/Redo:---------------------------------------------------------------------------------------------------

        self.undoStack = QUndoStack(self)
        self.undoStack.setUndoLimit(10)

        self.L_Row = []
        self.L_Column = []
        self.L_Text0 = []
        self.L_Text1 = []

        self.view.pressed.connect(self.InitialText)
        self.view.model().dataChanged.connect(self.FinalText)

    def InitialText(self, signal):
        self.Row = signal.row()
        self.Column = signal.column()
        Model = self.view.model()

        self.Text0 = Model.data(Model.index(self.Row, self.Column), 0).toString()

        self.L_Row.append(self.Row)
        self.L_Column.append(self.Column)
        self.L_Text0.append(self.Text0)
        # print self.L_Text0

    def FinalText(self):
        View = self.view
        Model = self.view.model()

        self.Text1 = Model.data(Model.index(self.Row, self.Column), 0).toString()
        self.L_Text1.append(self.Text1)

        for i in range(len(self.L_Text0)):
            if not (self.L_Text0[i] == self.L_Text1[i]):
                command = CommandEdit(View, Model, self.L_Row[i], self.L_Column[i],
                                  self.L_Text0[i], self.L_Text1[i], "ABC")
                self.undoStack.push(command)

# ContextMenu:---------------------------------------------------------------------------------------------------

    def contextMenuEvent(self, event):
        menu = QMenu(self)

        UndoAction = self.undoStack.createUndoAction(self)
        UndoAction.setText("&Undo")
        menu.addAction(UndoAction)
        UndoAction.setShortcuts(QKeySequence.Undo)
        self.connect(UndoAction, SIGNAL("triggered()"), self.undoStack.undo)

        RedoAction = self.undoStack.createUndoAction(self)
        RedoAction.setText("&Redo")
        menu.addAction(RedoAction)
        RedoAction.setShortcuts(QKeySequence.Redo)
        self.connect(RedoAction, SIGNAL("triggered()"), self.undoStack.redo)

        menu.exec_(event.globalPos())

# QUndoCommand Class:---------------------------------------------------------------------------------------------------

class CommandEdit(QUndoCommand):

    def __init__(self, View, Model, RowIndex, ColumnIndex, Text0, Text1, description):
        super(CommandEdit, self).__init__(description)
        self.view = View
        self.model = Model
        self.rowIndex = RowIndex
        self.columnIndex = ColumnIndex
        self.text0 = Text0
        self.text1 = Text1

    def undo(self):
        self.model.setData(self.model.index(self.rowIndex, self.columnIndex), QVariant(self.text0))

    def redo(self): # Error occurred while executing this function. 
        self.model.setData(self.model.index(self.rowIndex, self.columnIndex), QVariant(self.text1))

# Code Execute:---------------------------------------------------------------------------------------------------

if __name__ == "__main__":

    app = QApplication(sys.argv)
    filename = os.path.join(os.path.dirname(__file__), "STD.db")
    db = QSqlDatabase.addDatabase("QSQLITE")
    db.setDatabaseName(filename)
    db.open()
    StudentQuery()
    form = Ui_Student()
    form.show()
    sys.exit(app.exec_())

我在定义
def InitialText
def FinalText
时是否做错了什么?
redo
-->
setData
-->
dataChanged
-->
FinalText
-->
push
redo
-->请告诉我定义上述命令的确切方法。我不明白。谢谢我只是建议对调用进行手动跟踪,以找到递归。我实际上没有测试任何东西。堆栈的
push
方法调用
redo
,因此这看起来很可能是错误源,不是吗?