kahsay kalayu
kahsay kalayu

Reputation: 1

Add context menu to a specific Qtablewdiget table column, Python

Am trying to populate a data to my Qtablewdiget with pyQt5. On top of that, i want to add a context menu on specific column of my table. I have implemented my Qmenu to pop-up on the whole of my table, but can some one help me on how to implement context menu action for a specific column.

See a snapshot of my further work, that i tried

from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import (QPushButton, QAction, QApplication, QLabel, QMainWindow, QMenu)
from PyQt5 import QtCore, QtGui, QtWidgets

# setting context menu policy on my table, "self.ui.tableWidgetGraph"
self.ui.tableWidgetGraph.setContextMenuPolicy(Qt.CustomContextMenu)

# setting context menu request  by calling a function,"self.on_context_menu"
self.ui.tableWidgetGraph.customContextMenuRequested.connect(self.on_context_menu)

# define table size
self.ui.tableWidgetGraph.setRowCount(length);
self.ui.tableWidgetGraph.setColumnCount(lenColumn);

def on_context_menu(self, point):
    # show context menu
    self.contextMenu = QMenu(self)
    Task_one_action = self.contextMenu.addAction("Task_one")
    self.contextMenu.addSeparator()
    Task_two_action = self.contextMenu.addAction("Task_two")
    self.contextMenu.addSeparator()
    quit_action = self.contextMenu.addAction("Quit")

    # I want to perform actions only for a single column(E.g: Context menu only for column 4 of my table
    # Need help here....???
    action = self.contextMenu.exec_(self.ui.tableWidgetGraph.mapToGlobal(point))

    self.selected_key = ""
    for self.item in self.ui.tableWidgetGraph.selectedItems():
        self.selected_key = self.item.text()

    if action == quit_action:
        print("Executing the [Quit/Exit] Action")
        qApp.quit()

    elif action == Task_one_action:
        print("Executing Search: [Task_one_action ]")

    elif action == Task_two_action:
        print("Executing Search: [Task_two_action ]")

Can some one guide me on how to perform Context actions only for a single column(E.g: Context menu only for selected items in column-4 of my table),. thanks

Upvotes: 0

Views: 2326

Answers (1)

musicamante
musicamante

Reputation: 48335

You can get the item at a certain position using itemAt and then use column(), but since it might be an empty item, it would return None no matter if the column exists.

Use indexAt() instead (which is inherited by QTableView, which is what QTableWidget is built upon) to get the model index:

    def on_context_menu(self, pos):
        index = self.ui.tableWidgetGraph.indexAt(pos)
        if index.isValid() and index.column() == 3:
            menu = QtWidgets.QMenu()
            menu.addAction('Action for column 4')
            menu.exec_(self.ui.tableWidgetGraph.viewport().mapToGlobal(pos))

index.isValid() is to check that an index actually exists at those coordinates: for example, if you click within the vertical range of the fourth column but at those coordinates there is no row set yet, you'll get an invalid index (which doesn't have any row or column).

This obviously means that if you need to get the menu for that column, no matter if a row exists at that point, the approach above won't work.
If that's the case, you'll need to check against the table header instead:

    def on_context_menu(self, pos):
        index = self.ui.tableWidgetGraph.indexAt(pos)
        validColumn = index.isValid() and index.column() == 3
        if not validColumn:
            left = self.ui.tableWidgetGraph.horizontalHeader().sectionPosition(3)
            width = self.ui.tableWidgetGraph.horizontalHeader().sectionSize(3)
            if left <= pos.x() <= left + width:
                validColumn = True
        if validColumn:
            menu = QtWidgets.QMenu()
            menu.addAction('Action for column 4')
            menu.exec_(self.ui.tableWidgetGraph.viewport().mapToGlobal(pos))

Upvotes: 1

Related Questions