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

时间:2015-08-17 14:32:22

标签: pyqt contextmenu qtreeview qstandarditem

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

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

我不知道如何修改此菜单。

提前致谢!

2 个答案:

答案 0 :(得分:2)

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

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

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

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

答案 1 :(得分:1)

我有一个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()