I would like to add an action to the "default" Contextual menu that shows up when editing QStandardItem's Text (wich is shown in a QTreeView)
This contextual menu seems to be the default contextual menu of QPlainTextEdit widget. There is the default actions : Undo, Redo, Copy, Paste, Delete, Select All. I want to add a custom action just here.
I have no clue on how to modify this menu.
Thanks in advance !
To customise the editor for a QTreeView
cell you need to create a QItemDelegate
and associate it with a column of your treeview.
Custom delegates can be more complex (eg to change the save/restore behaviour of the editor) but in this case we just want to change which class it is using to instantiate the editor widget:
class CustomDelegate(QItemDelegate):
def createEditor(self, parent, option, index):
editor = CustomLineEdit(parent)
return editor
This will ensure the editor is now a CustomLineEdit
widget, which can have any added functionality you wish (like a custom context menu). In my example below, I use a slightly modified version of the answer provided by Achayan to implement this CustomLineEdit
.
You assign a custom delegate to a column with the following code (in this case I've chosen column 0 of the treeview):
# Create custom Delegate which instantiates our custom editor
delegate = CustomDelegate()
# Set this delegate for the first column only
treeview.setItemDelegateForColumn(0, delegate)
Full Code
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_()