目标
 在本章节,我设置了6个按键事件来模拟,实际的操作,分别是数字键1-5,和H
- Key_1 代表事件 ItemA(模拟实际的操作)
- Key_2 代表事件 ItemB
- Key_3 代表事件 ItemC
- Key_4 undo
- Key_5 redo
- Key_H 查看信息
每当执行一次事件时,事件就会被存储到历史堆栈里,最高上限为8,并且会记录当前位置 undo: 将位置往回移动,直到位置为0时 redo: 将位置向前移动,直到位置为历史堆栈最前面 查看信息:查看当前历史堆栈里面的内容,和当前位置
其中: 当历史堆栈达到上限后,新的事件将会存储在最前面,而前面的事件存储,将会往后移动一格 当undo后执行新的事件,则会将前面的事件清空(因为已经偏离了之前的历史堆栈)
实现
处理历史堆栈
新建文件node_scene_history.py 它将建立历史堆栈,负责管理Scene的历史堆栈,包括储存,undo,redo等功能
DEBUG = True
class SceneHistory():
def __init__(self,scene):
self.scene = scene
self.history_stack = []
self.history_current_step = -1
self.history_limit = 8
def undo(self):
if DEBUG:
print('undo')
if self.history_current_step > 0:
self.history_current_step -= 1
self.restoreHistory()
def redo(self):
if DEBUG:
print('redo')
if self.history_current_step + 1 < len(self.history_stack):
self.history_current_step += 1
self.restoreHistory()
def restoreHistory(self):
if DEBUG:
print("回溯历史————现在的位置:%d" % self.history_current_step,
"{%d}" % len(self.history_stack))
self.restoreHistoryStamp(self.history_stack[self.history_current_step])
def storeHistory(self, desc):
if DEBUG:
print("储存历史%s" % desc, "————现在的位置:%d" % self.history_current_step,
"{%d}" % len(self.history_stack))
if self.history_current_step+1 < len(self.history_stack):
self.history_stack = self.history_stack[0:self.history_current_step+1]
if self.history_current_step+1 >=self.history_limit:
self.history_stack = self.history_stack[1:]
self.history_current_step -= 1
hs = self.createHistoryStamp(desc)
self.history_stack.append(hs)
self.history_current_step += 1
if DEBUG: print("将步数设置为", self.history_current_step)
def createHistoryStamp(self,desc):
return desc
def restoreHistoryStamp(self, history_stamp):
if DEBUG:print("RHS",history_stamp)
其中
- self.history_stack 用于存储历史
- self.history_current_step 是当前在整个历史堆栈中的位置
- self.history_limit = 8 历史堆栈上限
createHistoryStamp(self,desc)将事件转化为历史,方便储存 restoreHistoryStamp(self, history_stamp)将当前场景变为当前位置的历史 storeHistory(self, desc):用于存储新的历史
为Scene添加SceneHistory
self.history = SceneHistory(self)
在View里做按键DEBUG
def keyPressEvent(self, event):
if event.key() == Qt.Key_Delete:
if not self.editingFlag:
self.deleteSelected()
else:
super().keyPressEvent(event)
elif event.key() == Qt.Key_S and event.modifiers() & Qt.ControlModifier:
self.grScene.scene.saveToFile('graph.json')
elif event.key() == Qt.Key_L and event.modifiers() & Qt.ControlModifier:
self.grScene.scene.loadFromFlie('graph.json')
elif event.key() == Qt.Key_1:
self.grScene.scene.history.storeHistory('ITEM A')
elif event.key() == Qt.Key_2:
self.grScene.scene.history.storeHistory('ITEM B')
elif event.key() == Qt.Key_3:
self.grScene.scene.history.storeHistory('ITEM C')
elif event.key() == Qt.Key_4:
self.grScene.scene.history.undo()
elif event.key() == Qt.Key_5:
self.grScene.scene.history.redo()
elif event.key() == Qt.Key_H:
print("历史堆栈长度:",len(self.grScene.scene.history.history_stack))
print("存储历史:",self.grScene.scene.history.history_stack)
else:
super().keyPressEvent(event)
新增6个按键事件,来方便我们进行调试
|