pythonpython-2.7pyqtqtableviewqtablewidget

Pass an instance via Context menu for QTableView and QTableWidget in PyQt


Uh, okay, friends, now I'm trying to add "export to Excel" feature for every table in my app like this:

...
def update_exportable_tables(self, *window):
    """
    Please don't ask why, here 'I know what I'm doing'
    """
    if not window:
        window = self.window

    for obj in window.__dict__:
        objname = obj.title().lower()
        the_object_itself = window.__dict__[obj]

        if isinstance(the_object_itself, (QTableWidget, QTableView)):
            the_object_itself.setContextMenuPolicy(Qt.CustomContextMenu)
            the_object_itself.customContextMenuRequested.connect(self.TableContextEvent)


def TableContextEvent(self, event):
    menu = QMenu()
    excelAction = menu.addAction(u"Export to Excel")
    excelAction.triggered.connect(self.export)
    action = menu.exec_(QCursor.pos())

def export(self):
    print 'Here I should do export'
...

Yeah, it works fine, but.... The question is how should I pass the clicked table instance to my export() function?


Solution

  • There are several different ways to solve this. Here's one way:

    def update_exportable_tables(self):
        for widget in QtGui.qApp.allWidgets():
            if isinstance(widget, QTableView):
                widget.setContextMenuPolicy(Qt.CustomContextMenu)
                widget.customContextMenuRequested.connect(self.showContextMenu)
    
    def showContextMenu(self, pos):
        table = self.sender()
        pos = table.viewport().mapToGlobal(pos)
        menu = QtGui.QMenu()
        excelAction = menu.addAction("Export to Excel")
        if menu.exec_(pos) is excelAction:
            self.export(table)
    
    def export(self, table):
        print 'Here I should do export:', table
    

    (NB: QTableWidget is a subclass of QTableView).