Я написал код для Отменить и повторить действий для QTableView , используя QUndoStack класс в PyQt4.
Действие отмены работает нормально; но когда я выполняю Повторить действие , я получаю "RuntimeError: максимальная глубина рекурсии превышена при вызове объекта Python."
Я использовал сигналы pressed
& dataChanged
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
?