PyQt 在编辑 QstandardItem 的文本时扩展现有的上下文菜单(在 QtreeView 中)

PyQt extend existing Contextual Menu when editing QstandardItem's Text (in a QtreeView)

我想在编辑 QStandardItem 的文本时显示的 "default" 上下文菜单中添加一个操作(显示在 QTreeView 中)

这个上下文菜单似乎是 QPlainTextEdit 小部件的默认上下文菜单。有默认操作:撤消、重做、复制、粘贴、删除、Select 全部。我想在这里添加一个自定义操作。

我不知道如何修改这个菜单。

提前致谢!

我有一个 QPlainTextEdit 的例子。您可以根据需要进行修改。希望这有帮助

class CustomLineEdit(QtGui.QPlainTextEdit):
    def __init__(self, parent = None):
        super(CustomLineEdit, self).__init__()
        self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.__contextMenu)

    def __contextMenu(self):
        self._normalMenu = self.createStandardContextMenu()
        self._addCustomMenuItems(self._normalMenu)
        self._normalMenu.exec_(QtGui.QCursor.pos())

    def _addCustomMenuItems(self, menu):
        menu.addSeparator()
        menu.addAction(u'Test', self.testFunc)

    def testFunc(self):
        print "Call"

class mainwindow(QtGui.QWidget):
    def __init__(self , parent = None):
        super(mainwindow, self).__init__()    
        self.setupgui()
    def setupgui(self):

        self.resize(800,600)
        self.setWindowTitle('test')
        newLayout = QtGui.QHBoxLayout()
        qlbl = CustomLineEdit()
        newLayout.addWidget(qlbl)
        self.setLayout(newLayout)
        self.show()


def main():

    app = QtGui.QApplication(sys.argv)
    ex = mainwindow()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

要为 QTreeView 单元格自定义编辑器,您需要创建一个 QItemDelegate 并将其与树视图的列相关联。

自定义委托可能更复杂(例如,更改编辑器的 save/restore 行为)但在这种情况下,我们只想更改 class 它用于实例化编辑器小部件的内容:

class CustomDelegate(QItemDelegate):
    def createEditor(self, parent, option, index):
        editor = CustomLineEdit(parent)                
        return editor

这将确保编辑器现在是一个 CustomLineEdit 小部件,它可以具有您希望的任何附加功能(如自定义上下文菜单)。在下面的示例中,我使用 提供的答案的略微修改版本来实现此 CustomLineEdit.

您使用以下代码将自定义委托分配给列(在本例中,我选择了树视图的第 0 列):

# Create custom Delegate which instantiates our custom editor
delegate = CustomDelegate()
# Set this delegate for the first column only
treeview.setItemDelegateForColumn(0, delegate)

完整代码

import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *

class CustomLineEdit(QLineEdit):
    def __init__(self, *args, **kwargs):
        super(CustomLineEdit, self).__init__(*args, **kwargs)
        self.setContextMenuPolicy(Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(self.__contextMenu)

    def __contextMenu(self):
        self._normalMenu = self.createStandardContextMenu()
        self._addCustomMenuItems(self._normalMenu)
        self._normalMenu.exec_(QCursor.pos())

    def _addCustomMenuItems(self, menu):
        menu.addSeparator()
        menu.addAction(u'Test', self.testFunc)

    def testFunc(self):
        print "Call"


class CustomDelegate(QItemDelegate):
    def createEditor(self, parent, option, index):
        editor = CustomLineEdit(parent)                
        return editor


if __name__ == "__main__":
    app = QApplication(sys.argv)

    # Create Widgets
    window = QMainWindow()
    widget = QWidget()
    layout = QVBoxLayout(widget)
    treeview = QTreeView()
    layout.addWidget(treeview)
    window.setCentralWidget(widget)
    window.show()

    # Create Model
    model = QStandardItemModel()
    model.setHorizontalHeaderLabels(['Header 1','Header 2'])
    treeview.setModel(model)

    # Create custom Delegate which instantiates our custom editor
    delegate = CustomDelegate()
    # Set this delegate for the first column only
    treeview.setItemDelegateForColumn(0, delegate)

    # Populate the model with some test data
    row1 = []
    row1.append(QStandardItem("asd"))
    row1.append(QStandardItem("fgh"))
    model.appendRow(row1)
    row2 = []
    row2.append(QStandardItem("qwe"))
    row2.append(QStandardItem("rty"))
    model.appendRow(row2)

    app.exec_()