RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1376399
Accepted
aqua
aqua
Asked:2022-06-29 22:07:04 +0000 UTC2022-06-29 22:07:04 +0000 UTC 2022-06-29 22:07:04 +0000 UTC

在 QTableWidget 中使用 Undo 框架

  • 772

如何实现撤销和重做操作QTableWidget?

让我们以一个简单的窗口为例QTableWidget,我们将在其中跟踪击键,组合键Ctrl+Z取消操作,Ctrl+Y重复。

from PyQt5 import QtWidgets, QtCore, QtGui


class Window(QtWidgets.QWidget):
    def __init__(self, parent = None):
        super(Window, self).__init__(parent)
        self.resize(400, 400)

        self.tableWidget = QtWidgets.QTableWidget(10, 10)

        self.vbox = QtWidgets.QVBoxLayout(self)
        self.vbox.addWidget(self.tableWidget)

    def keyPressEvent(self, event):
        if event.text() == '<0x1a>':
            self.tableWidget.undo()
        elif event.text() == '<0x19>':
            self.tableWidget.redo()


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    window = Window()
    window.show()
    sys.exit(app.exec_())

python
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    S. Nick
    2022-07-10T07:04:19Z2022-07-10T07:04:19Z

    尝试在下面检查。如果这是您需要的,您可以自己添加键盘快捷键跟踪。

    import sys
    from PyQt5 import QtCore, QtGui, QtWidgets
    
    
    class CommandTextEdit(QtWidgets.QUndoCommand):
        def __init__(self, window, index, oldText, newText): 
            super(CommandTextEdit,self).__init__()
            self.index = index
            self.window = window
            self.oldText = oldText
            self.newText = newText
    
        def redo(self):
            self.index.model().itemDataChanged.disconnect(self.window.itemDataChangedSlot)
            self.index.model().setData(self.index, self.newText, QtCore.Qt.EditRole)
            self.index.model().itemDataChanged.connect(self.window.itemDataChangedSlot)
    
        def undo(self):
            self.index.model().itemDataChanged.disconnect(self.window.itemDataChangedSlot)
            self.index.model().setData(self.index, self.oldText, QtCore.Qt.EditRole)
            self.index.model().itemDataChanged.connect(self.window.itemDataChangedSlot)
    
    
    class Model(QtCore.QAbstractTableModel):
        itemDataChanged = QtCore.pyqtSignal(object, object, object, object)
    
        def __init__(self, data = [[]], parent = None):
            super(Model,self).__init__(parent)
            self._data = data
    
        def rowCount(self, parent=QtCore.QModelIndex()):
            return len(self._data)
           
        def columnCount(self, parent=QtCore.QModelIndex()):
            return len(self._data[0])
    
        def data(self, index, role):
            row = index.row()
            column = index.column()
            if role == QtCore.Qt.EditRole:
                return self._data[row][column]
    
            if role == QtCore.Qt.DisplayRole:
                value = self._data[row][column]
                return value      
    
        def model(self):
            return self
    
        def flags(self, index):
            return QtCore.Qt.ItemIsEditable | \
                   QtCore.Qt.ItemIsEnabled  | \
                   QtCore.Qt.ItemIsSelectable
    
        def setData(self, index, value, role = QtCore.Qt.UserRole + 1):
            if index.isValid():
               if role == QtCore.Qt.EditRole:
                    oldValue = self.data(index, role)
                    self._data[index.row()][index.column()] = value
                    self.dataChanged.emit(index, index)
                    if oldValue != value:
                        self.itemDataChanged.emit(index, oldValue, value, role)
                    return True
            return False
            
    
    class Window(QtWidgets.QMainWindow):
        def __init__(self, parent = None):
            super(Window,self).__init__(parent)
            self.centralWidget = QtWidgets.QWidget()
            self.setCentralWidget(self.centralWidget)
            self.setWindowTitle('Widget Mapping GUI')
            mainlayout = QtWidgets.QVBoxLayout(self.centralWidget)
            self.mapper = None
    
            rowCount    = 5
            columnCount = 5
            data = [
                [f'{j}-{i}' for i in range(columnCount)]
                 for j in range(rowCount)
            ]
            self.model = Model(data)
            
            #QUndoStack
            self.undoStack = QtWidgets.QUndoStack()
            self.stackView = QtWidgets.QUndoView(self.undoStack)
    
            self.createActions()
            self.makeConnections()
            self.tableViewMethod()
           
            layout = QtWidgets.QVBoxLayout()
            mainlayout.addLayout(layout)
            layout.addWidget(self.tableView)
    
        def createActions(self):
            self.undoAct = QtWidgets.QAction("Undo", self)
            self.undoAct.setShortcut(QtGui.QKeySequence.Undo)
            self.undoAct.triggered.connect(self.undoStack.undo)
            self.redoAct = QtWidgets.QAction("Redo", self)
            self.redoAct.setShortcut(QtGui.QKeySequence.Redo)
            self.redoAct.triggered.connect(self.undoStack.redo)
            self.toolbar = self.addToolBar('')
            self.toolbar.addAction(self.undoAct)
            self.toolbar.addAction(self.redoAct)
    
        def tableViewMethod(self):
            self.tableView = QtWidgets.QTableView()
            self.tableView.setModel(self.model)
            self.tableView.setWindowTitle('tableView')
    
        def makeConnections(self):
            self.model.itemDataChanged.connect(self.itemDataChangedSlot)
    
        def setModel(self, model):
            self.mapper = QtWidgets.QDataWidgetMapper(self)
            self.mapper.setOrientation(QtCore.Qt.Horizontal)
            self.mapper.setModel(model)
            
        def itemDataChangedSlot(self, index, oldValue, value, role):
            if role == QtCore.Qt.EditRole:
                command = CommandTextEdit(
                    self, 
                    index, 
                    oldValue, 
                    value
                )
                self.undoStack.push(command)
    
    
    if __name__ == '__main__':
        app = QtWidgets.QApplication(sys.argv)
        w = Window()
        w.resize(600, 300)
        w.show()
        sys.exit(app.exec_())
    

    在此处输入图像描述

    • 1

相关问题

  • 是否可以以某种方式自定义 QTabWidget?

  • telebot.anihelper.ApiException 错误

  • Python。检查一个数字是否是 3 的幂。输出 无

  • 解析多个响应

  • 交换两个数组的元素,以便它们的新内容也反转

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    我看不懂措辞

    • 1 个回答
  • Marko Smith

    请求的模块“del”不提供名为“default”的导出

    • 3 个回答
  • Marko Smith

    "!+tab" 在 HTML 的 vs 代码中不起作用

    • 5 个回答
  • Marko Smith

    我正在尝试解决“猜词”的问题。Python

    • 2 个回答
  • Marko Smith

    可以使用哪些命令将当前指针移动到指定的提交而不更改工作目录中的文件?

    • 1 个回答
  • Marko Smith

    Python解析野莓

    • 1 个回答
  • Marko Smith

    问题:“警告:检查最新版本的 pip 时出错。”

    • 2 个回答
  • Marko Smith

    帮助编写一个用值填充变量的循环。解决这个问题

    • 2 个回答
  • Marko Smith

    尽管依赖数组为空,但在渲染上调用了 2 次 useEffect

    • 2 个回答
  • Marko Smith

    数据不通过 Telegram.WebApp.sendData 发送

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5