How To Add Context Menu Into QTreeWidget
GOAL
Today’s goal is to add context menu to the QTreeWidget in PySide.
Environment
Windows 10
Python 3.8.7
PySide2 (5.15.2)
Method
Change the ContextMenuPolicy of the widget.
Use CustomContextMenu if you’d like to connect your function to the signal that is emitted when the context menu is requested by actions such as right-clicked. See Qt::ContextMenuPolicy in Qt Documentation for details about ContextMenuPolocy types.
self.tree_widget = QTreeWidget() self.tree_widget.setContextMenuPolicy(Qt.CustomContextMenu) self.tree_widget.customContextMenuRequested.connect(self._show_context_menu)
And define the function to connect. Please use exec_() instead of show() to display the menu. The mapToGlobal function is used to determines the position to display the menu.
# the function to display context menu def _show_context_menu(self, position): display_action1 = QAction("Display Selection") display_action1.triggered.connect(self.display_selection) menu = QMenu(self.tree_widget) menu.addAction(display_action1) menu.exec_(self.tree_widget.mapToGlobal(position))
Complete Code
cotext_menu_test.py
import sys from PySide2.QtWidgets import * from PySide2.QtCore import Qt class MyMainWindow(QMainWindow): def __init__(self, parent=None): super(MyMainWindow, self).__init__(parent) self._generate_ui() self._init_tree_widget() def _generate_ui(self): main_widget = QWidget() main_layout = QVBoxLayout() main_widget.setLayout(main_layout) self.setCentralWidget(main_widget) self.tree_widget = QTreeWidget() self.tree_widget.setSelectionMode(QAbstractItemView.ExtendedSelection) #----------add context menu-------------------------------------- self.tree_widget.setContextMenuPolicy(Qt.CustomContextMenu) self.tree_widget.customContextMenuRequested.connect(self._show_context_menu) #---------------------------------------------------------------- main_layout.addWidget(self.tree_widget) def _init_tree_widget(self): headers = ["header1", "header2"] self.tree_widget.setHeaderLabels(headers) tree_widget_item1 = QTreeWidgetItem(["group1"]) tree_widget_item1.addChild(QTreeWidgetItem(["item1_1", "item1_2"])) self.tree_widget.addTopLevelItem(tree_widget_item1) tree_widget_item2 = QTreeWidgetItem(["group2"]) self.tree_widget.addTopLevelItem(tree_widget_item2) tree_widget_item2.addChild(QTreeWidgetItem(["item2_1", "item2_2"])) tree_widget_item2.addChild(QTreeWidgetItem(["item3_1", "item3_2"])) # the function to display context menu def _show_context_menu(self, position): display_action1 = QAction("Display Selection") display_action1.triggered.connect(self.display_selection) menu = QMenu(self.tree_widget) menu.addAction(display_action1) menu.exec_(self.tree_widget.mapToGlobal(position)) # the action executed when menu is clicked def display_selection(self): column = self.tree_widget.currentColumn() text = self.tree_widget.currentItem().text(column) print("right-clicked item is " + text) def launch(): app = QApplication.instance() if not app: app = QApplication(sys.argv) widget = MyMainWindow() widget.show() app.exec_() launch()
Result
When the item “item1_2” is right-clicked, the menu appears.
Click the “Display Selection”, the message is displayed.