我自己的问题的答案:
我更改了 Momo 的代码以使其适合我,并且添加了删除多个单元格以及通过粘贴或删除撤消错误的可能性。撤消操作仅在光标所在的表格内进行。
有没有更好的方法可以做到这一点,或者您可以提供改进建议吗?
import PySide6.QtWidgets as QtWidgets
from PySide6 import QtCore, QtGui
from PySide6.QtGui import QGuiApplication
class CopyPasteDelTableWidget(QtWidgets.QTableWidget):
def __init__(self, n_rows, n_columns):
super().__init__(n_rows, n_columns)
self.forundo = []
self.setSelectionMode(QtWidgets.QAbstractItemView.ContiguousSelection)
self.installEventFilter(self)
def eventFilter(self, source, event):
if event.type() == QtCore.QEvent.KeyPress:
if event == QtGui.QKeySequence.Copy:
self.copySelection()
return True
elif event == QtGui.QKeySequence.Paste:
self.pasteSelection()
return True
elif event == QtGui.QKeySequence.Delete:
self.deleteSelection()
return True
elif event == QtGui.QKeySequence.Cut:
self.copySelection()
self.deleteSelection()
return True
elif event == QtGui.QKeySequence.Undo:
self.undoSelection()
return True
return super(QTableWidget, self).eventFilter(source, event)
def deleteSelection(self):
self.forundo.append([self.selectedRanges()[0].topRow(), self.selectedRanges()[0].leftColumn(), []])
for i_row in range(self.selectedRanges()[0].topRow(), self.selectedRanges()[0].bottomRow() + 1):
undorow = []
for i_col in range(self.selectedRanges()[0].leftColumn(), self.selectedRanges()[0].rightColumn() + 1):
undorow.append(self.item(i_row, i_col).text())
self.setItem(i_row, i_col, QtWidgets.QTableWidgetItem(''))
self.forundo[-1][2].append(undorow)
def copySelection(self):
copied = ''
for row in range(self.selectedRanges()[0].topRow(), self.selectedRanges()[0].bottomRow() + 1):
for col in range(self.selectedRanges()[0].leftColumn(), self.selectedRanges()[0].rightColumn() + 1):
copied += self.item(row, col).text() + '\t'
copied = copied[:-1] + '\n'
QGuiApplication.clipboard().setText(copied)
def pasteSelection(self):
if not QGuiApplication.clipboard():
return
copied = QGuiApplication.clipboard().text().split('\n')
self.forundo.append([self.selectedRanges()[0].topRow(), self.selectedRanges()[0].leftColumn(), []])
if copied[-1] == '':
copied = copied[:-1]
for i_line, line in enumerate(copied):
copied[i_line] = line.split('\t')
for i_row, row in enumerate(copied):
undorow = []
k_row = i_row + self.selectedRanges()[0].topRow()
if k_row < self.rowCount():
for i_col, col in enumerate(row):
k_col = i_col + self.selectedRanges()[0].leftColumn()
if k_col < self.columnCount():
undorow.append(self.item(k_row, k_col).text())
self.setItem(k_row, k_col, QtWidgets.QTableWidgetItem(col))
self.forundo[-1][2].append(undorow)
def undoSelection(self):
if len(self.forundo) > 0:
prevundo = self.forundo.pop()
self.setCurrentCell(prevundo[0], prevundo[1])
for i_row, row in enumerate(prevundo[2]):
for i_col, col in enumerate(row):
self.setItem(i_row + prevundo[0], i_col + prevundo[1], QtWidgets.QTableWidgetItem(col))