Damia
Damia

Reputation: 171

Modify QTableWidgetItem context menu when editing

I'm trying to add actions to the context menu that pops up when I right click while editing a cell’s content in a QTableWidget. I tried redefining the contextMenuEvent() method from QTableWidget but it is never called in this context. I also tried to call cellWidget() method on the items, but as I expected it returned None. I'm guessing that a temporary QLineEdit widget is created whenever a cell is in edit mode but couldn't find anything to confirm that.

Is there any way to access the context menu of QTableWidgetItems when in edit mode?

I've looked extensively through the documentation but to no avail.

Upvotes: 1

Views: 462

Answers (1)

eyllanesc
eyllanesc

Reputation: 244291

The context menu that you must handle is the editor provided by the delegate. So in this case a QStyledItemDelegate must be implemented:

from PyQt5 import QtCore, QtGui, QtWidgets


class StyledItemDelegate(QtWidgets.QStyledItemDelegate):
    def createEditor(self, parent, option, index):
        editor = super().createEditor(parent, option, index)
        if isinstance(editor, QtWidgets.QLineEdit):
            editor.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
            editor.setProperty("index", QtCore.QPersistentModelIndex(index))
            editor.customContextMenuRequested.connect(self.handle_context_menu)
        return editor

    def handle_context_menu(self, pos):
        editor = self.sender()
        if isinstance(editor, QtWidgets.QLineEdit):
            index = editor.property("index")
            menu = editor.createStandardContextMenu()
            action = menu.addAction("New Action")
            action.setProperty("index", index)
            action.triggered.connect(self.handle_add_new_action_triggered)
            menu.exec_(editor.mapToGlobal(pos))

    def handle_add_new_action_triggered(self):
        action = self.sender()
        if isinstance(action, QtWidgets.QAction):
            index = action.property("index")
            print(index.row(), index.column(), index.data())


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)

    view = QtWidgets.QTableWidget(3, 5)
    delegate = StyledItemDelegate(view)
    view.setItemDelegate(delegate)
    view.resize(640, 480)
    view.show()

    sys.exit(app.exec_())

Upvotes: 2

Related Questions