- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
精简版
如何在 PySide/PyQt 中实现对 QListWidgetItems
所做编辑的撤消功能?
来自 Qt 教程的提示?
下面为 Qt 用户 (c++) 编写的教程可能有答案,但我不是 c++ 人,所以有点迷茫:Using Undo/Redo with Item Views
更长的版本
我正在使用 QListWidget
来了解 PyQt 的 Undo Framework (在主题的 an article 的帮助下)。当我自己执行一个命令时(比如从列表中删除一个项目),我可以接受撤消/重做。
我还想让小部件中的 QListWidgetItems
可编辑。这很简单:只需将 ItemIsEditable
标志添加到每个项目即可。问题是,我如何将此类编辑推送到撤消堆栈,以便我可以撤消/重做它们?
下面是一个简单的工作示例,它显示了一个列表,让您可以删除项目,并撤消/重做此类删除。该应用程序显示列表和撤消堆栈。需要做什么才能对该堆栈进行编辑?
简单的工作示例
from PySide import QtGui, QtCore
class TodoList(QtGui.QWidget):
def __init__(self):
QtGui.QWidget.__init__(self)
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
self.initUI()
self.show()
def initUI(self):
self.todoList = self.makeTodoList()
self.undoStack = QtGui.QUndoStack(self)
undoView = QtGui.QUndoView(self.undoStack)
buttonLayout = self.buttonSetup()
mainLayout = QtGui.QHBoxLayout(self)
mainLayout.addWidget(undoView)
mainLayout.addWidget(self.todoList)
mainLayout.addLayout(buttonLayout)
self.setLayout(mainLayout)
self.makeConnections()
def buttonSetup(self):
#Make buttons
self.deleteButton = QtGui.QPushButton("Delete")
self.undoButton = QtGui.QPushButton("Undo")
self.redoButton = QtGui.QPushButton("Redo")
self.quitButton = QtGui.QPushButton("Quit")
#Lay them out
buttonLayout = QtGui.QVBoxLayout()
buttonLayout.addWidget(self.deleteButton)
buttonLayout.addStretch()
buttonLayout.addWidget(self.undoButton)
buttonLayout.addWidget(self.redoButton)
buttonLayout.addStretch()
buttonLayout.addWidget(self.quitButton)
return buttonLayout
def makeConnections(self):
self.deleteButton.clicked.connect(self.deleteItem)
self.quitButton.clicked.connect(self.close)
self.undoButton.clicked.connect(self.undoStack.undo)
self.redoButton.clicked.connect(self.undoStack.redo)
def deleteItem(self):
rowSelected=self.todoList.currentRow()
rowItem = self.todoList.item(rowSelected)
if rowItem is None:
return
command = CommandDelete(self.todoList, rowItem, rowSelected,
"Delete item '{0}'".format(rowItem.text()))
self.undoStack.push(command)
def makeTodoList(self):
todoList = QtGui.QListWidget()
allTasks = ('Fix door', 'Make dinner', 'Read',
'Program in PySide', 'Be nice to everyone')
for task in allTasks:
todoItem=QtGui.QListWidgetItem(task)
todoList.addItem(todoItem)
todoItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
return todoList
class CommandDelete(QtGui.QUndoCommand):
def __init__(self, listWidget, item, row, description):
super(CommandDelete, self).__init__(description)
self.listWidget = listWidget
self.string = item.text()
self.row = row
def redo(self):
self.listWidget.takeItem(self.row)
def undo(self):
addItem = QtGui.QListWidgetItem(self.string)
addItem.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
self.listWidget.insertItem(self.row, addItem)
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
myList=TodoList()
sys.exit(app.exec_())
注意我发布了一个电子arlier version of this question在 QtCentre。
最佳答案
你提到的那个教程真的不是很有帮助。 View 的undo-redo实现方式确实有很多种,我们只需要选择最简单的一种即可。如果您处理的是小列表,最简单的方法是在每次更改时保存所有数据,并在每次撤消或重做操作时从头开始恢复完整列表。
如果您仍然想要原子更改列表,您可以使用 QListWidget::itemChanged
信号跟踪用户所做的编辑。这有两个问题:
QObject::blockSignals
调用中以阻止不需要的信号。QListWidget::currentItemChanged
假设用户不会找到一种方法来编辑一个项目而不首先是当前的。所以这是使它工作的变化(除了在两个地方添加 ItemIsEditable
标志):
def __init__(self):
#...
self.todoList.itemChanged.connect(self.itemChanged)
self.todoList.currentItemChanged.connect(self.currentItemChanged)
self.textBeforeEdit = ""
def itemChanged(self, item):
command = CommandEdit(self.todoList, item, self.todoList.row(item),
self.textBeforeEdit,
"Rename item '{0}' to '{1}'".format(self.textBeforeEdit, item.text()))
self.undoStack.push(command)
def currentItemChanged(self, item):
self.textBeforeEdit = item.text()
以及新的变化类:
class CommandEdit(QtGui.QUndoCommand):
def __init__(self, listWidget, item, row, textBeforeEdit, description):
super(CommandEdit, self).__init__(description)
self.listWidget = listWidget
self.textBeforeEdit = textBeforeEdit
self.textAfterEdit = item.text()
self.row = row
def redo(self):
self.listWidget.blockSignals(True)
self.listWidget.item(self.row).setText(self.textAfterEdit)
self.listWidget.blockSignals(False)
def undo(self):
self.listWidget.blockSignals(True)
self.listWidget.item(self.row).setText(self.textBeforeEdit)
self.listWidget.blockSignals(False)
关于python - 如何撤消 PySide/PyQt 中 QListWidgetItem 的编辑?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28954565/
我正在尝试使用 QListWidgetItems 制作 QListWidget。 我希望 QListWidgetItems 具有边框和背景,例如绿。 所选项目应该有另一个背景,例如红色的。 我试图用样
我有一个非常简单的QListWidget对象,我想构建一个文件夹列表。当我将一个项目添加到我的列表中时,我会执行以下操作: void LessCC::on_addFolderButton_clicke
我已经定义了一个小部件,它包含一个 QLabel(和其他元素),它应该显示换行的文本。这个 QLabel 有: 横向策略:最小值 垂直策略:MinimumExpanding 自动换行:真 小部件有:
我有一个 QDialog,我用它从 SQL 表中显示的项目列表中进行选择。选择项目后,我需要返回表并读取所选项目的所有数据。我想将 SQL ID 添加到 WidgetItem。 我创建了一个继承自 Q
我在表单中有一个 QListWidget,其中的 QListWidgetItem 显示“添加新的”。当我点击它时,我希望发生一系列事情: QInputDialog::getText 请求新项目的内容。
我正在尝试将 QlistWidgetItem 设置为使用 in 存储对象。我正在使用 setData 函数来实现此目的。我可以将数据存储在列表 A 中的项目中。但是我试图将 QlistWidgetIt
我有一个 QListWidgetItem,它有一个 QWidget 和一些 QLabels。标签(imageLabel、titleLabel 和 descriptionLabel)的高度因文本长度而异
我现在真的卡住了..我的应用程序可以通过单击创建(动画)帧,可以移动、删除或编辑这些帧。我想要某种右键单击上下文菜单来删除它们。 我现在的尝试是创建一个 QListWidget,并在其中插入 QLis
我正在开发我的第一个 QT 应用程序,但我遇到了 QListWidgetItems 的问题。 我会有不同类型的列表。对于复选框列表,使用: listElement[i]->setFlags(Qt::I
我有一个 QListWidget,它在 iconMode 中用作 viewMode。当我为 QListWidgetItem 设置 QIcon 和文本时,图标显示在文本的顶部。如果我在 listMode
我做了一个 QListWidget .在 QLisitWidgetItems , 我加了一个 QVBoxLayout .那个QVBoxLayout包含三个 QLabels .如何获取里面的值 QLab
我偶然发现了这个(显然,这是一个更大的应用程序的摘录): import sys from PySide2.QtCore import * from PySide2.QtGui import * fro
所以基本上我刚刚开始学习 PyQt,我想在 listWidget 中获取元素的文本,但每次我尝试 self.listWidget.currentItem().text() 时都会抛出错误。为什么? i
我正在编写一种搜索算法,用于搜索 QListWidget 并根据用户在搜索栏中键入的内容返回相关匹配项。我希望所有匹配项都以淡黄色突出显示。 例如: 如果用户在搜索栏中键入“ilt”,我想用文本“Wr
下面的代码创建了一个 QListWidget,并为 QListWidgetItem 分配了缩略图。 如果您展示如何在 QListWidgetItem 周围制作彩色边框,我将不胜感激 这是显示概念的 P
如果我们使用 QListWidgetItem 引用进行操作,我们如何更改文本的大小?任何帮助将不胜感激。 最佳答案 试试这个,使用 QListWidgetItem::font() 方法获取项目的当前字
我有一个 QListWidgetItem* 并且想知道是否可以从这个指针中提取行而不遍历整个列表 最佳答案 如果需要行号,请使用下面的函数: int QListWidget::row(const QL
我有一个带有 QListWidget 的表单,我在其中反复添加新项目。一切都完美无瑕,除了一件事:无论我传递给它们什么标志,这些项目都是三态的。因此,必须单击该项目两次才能选中/取消选中它们。我该怎么
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
我有一个 QListWidget的日历。每个QListWidgetItem在逻辑上与 Calendar 的实例相关联,这是一个属于应用程序模型端的类。 我可以使用 QListWidgetItem::s
我是一名优秀的程序员,十分优秀!