我目前使用的是 subclass 的QTableView
和QAbstractTableModel
.
在 Stackoverflow 上搜索了一阵子,看起来正统的做法之一是在 Model 中包含一个QUndoStack
,然后另外写一个 subclass QUndoCommand
的类。但是我没有搞明白,到底在哪里调用最后这个类,所以也就没写出来。
我目前用的是笨办法。因为表格中的数据很小,大概就 500KB 左右。每次进行修改,就把上一次的数据直接深拷贝。同时在 View 里头截获 keypress,如果是Ctrl+Z
就调用 Model 中的undo()
,直接把深拷贝的原样直接覆盖到现有的数据上。简化后的代码如下:
# Model
class SlotConfigModel(QAbstractTableModel):
def __init__(self, data):
super(SlotConfigModel, self).__init__()
self._data = data
self._olddata: list = []
self._lable = ("id", "Probability", "Reel 1", "Reel 2", "Reel 3")
def setData(self, index, value, role=None):
if role == Qt.EditRole:
# 每次编辑都把未修改前的 data 存档(需要深复制因为 data 是 list),undo 的时候覆盖。
self._olddata.append(copy.deepcopy(self._data))
print("Old data saved to list")
row = index.row()
col = index.column()
self._data[index.row()][index.column()] = value
return True
return False
def undo(self):
if len(self._olddata) > 0:
self._data = copy.deepcopy(self._olddata[-1])
print("Undo successful!")
self._olddata.pop()
else:
print("Nothing to Undo!")
# View
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.tableview = QTableView()
self.horizontal_header = self.tableview.horizontalHeader()
self.horizontal_header.setStretchLastSection(True)
data = [
[15, 0.13, "[101]", "[101]", "[101]"],
[15, 0.03, "[101]", "[101]", "[102, 104, 5, 2, 1]"],
[15, 0.04, "[101]", "[102;104;5;2;1]", "[101;102;104;5;2;1]"],
[16, 0.20, "[5]", "[5]", "[5]"],
[16, 0.50, "[101]", "[5]", "[102, 104, 5, 2, 1]"],
[16, 0.10, "[5]", "[102;104;5;2;1]", "[101;102]"]
]
self.model = SlotConfigModel(data)
self.tableview.setModel(self.model)
self.setCentralWidget(self.tableview)
def keyPressEvent(self, event):
if event.key() == (Qt.Key_Control and Qt.Key_Z):
# 如果 Ctrl-Z 则调用 Model 中的 undo()
self.model.undo()
# 手动更新 View,否则直到下一次交互才更新
self.tableview.viewport().update()
QTableView.keyPressEvent(self.tableview, event)
我觉得这个不是长久之计,比如说我还要写Insertrow()
等方法,这样弄起来还是颇为费劲,最好是能用QUndoCommand
来,求问有没有什么具体的范例?多谢!
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.