comment ajouter un menu de clic droit à chaque cellule de Qtableview dans PyQt

je veux ajouter un menu de clic droit pour supprimer, renommer ou ouvrir l'image dans chacune des cellules de QTAbleView dans le menu de clic droit, j'ai essayé et j'ai trouvé tout le monde essaye d'ajouter un menu à un en-tête dans tableview, j'ai essayé ci-dessous, mais cela ne semble pas fonctionner dans le code ci-dessous..

class GalleryUi(QtGui.QTableView):
    """ Class contains the methods that forms the
        UI of Image galery
    """
    def __init__(self, imagesPathLst=None, parent=None):
        super(GalleryUi, self).__init__(parent)
        self.__sw = QtGui.QDesktopWidget().screenGeometry(self).width()
        self.__sh = QtGui.QDesktopWidget().screenGeometry(self).height()
        self.__animRate = 1200
        self._imagesPathLst = imagesPathLst
        self._thumb_width = 200
        self._thumb_height = self._thumb_width + 20
        self.setUpWindow(initiate=True)

        self._startControlBar()

        self._connections()

    def contextMenuEvent(self, event):

        index = self.indexAt(event.pos())
        menu = QtGui.QMenu()
        renameAction = QtGui.QAction('Exit', self)
        renameAction.triggered.connect(self.close)
        self.menu.addAction(renameAction)
        self.menu.popup(QtGui.QCursor.pos())

    def closeEvent(self,event):
        # in case gallery is launched by Slideshow this is not needed
        if hasattr(self, 'bar'):
            self.bar.close()

    def _startControlBar(self):
        if not self._slideShowWin:
            self.bar = controlBar.ControlBar()
            self.bar.show()
            self.bar.exitBtn.clicked.connect(self.close)
            self.bar.openBtn.clicked.connect(self.selectSetNewPath)


    def _connections(self):
        self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.connect(self, QtCore.SIGNAL(self.customContextMenuRequested(QtCore.QPoint)), self, QtCore.SLOT(displayMenu(QtCore.QPoint)))

    def displayMenu(self, pos):
        self.menu = QtGui.QMenu()
        self.menu.addAction(self.close)
        self.menu.exec_(self.mapToGlobal(event.pos()))

    def selectSetNewPath(self):

        path = utils._browseDir("Select the directory that contains images")
        self._imagesPathLst = utils.ingestData(path)
        # sets model when new folder is choosen
        self.updateModel()

    def setUpWindow(self, initiate=False):
        """ Method to setup window frameless and fullscreen,
            setting up thumbnaul size and animation rate
        """

        if not self._imagesPathLst:
            self.selectSetNewPath()
        # sets model once at startup when window is being drawn!
        if initiate:
            self.updateModel()
        self.setGeometry(0, 0, self.__sw, self.__sh)
        self.setColumnWidth(self._thumb_width, self._thumb_height)
        self.setShowGrid(False)
        self.setWordWrap(True)
        self.show()

        self.resizeColumnsToContents()
        self.resizeRowsToContents()
        self.selectionModel().selectionChanged.connect(self.selChanged)

    def updateModel(self):
        col = self.__sw/self._thumb_width 
        self._twoDLst = utils.convertToTwoDList(self._imagesPathLst, col)
        lm = MyListModel(self._twoDLst, col,
            (self._thumb_width, self._thumb_height), self)
        self.setModel(lm)



    def keyPressEvent(self, keyevent):
        """ Capture key to exit, next image, previous image,
            on Escape , Key Right and key left respectively.
        """
        event = keyevent.key()
        if event == QtCore.Qt.Key_Escape:
            self._exitGallery()



def main(imgLst=None):
    """ method to start gallery standalone
    """
    app = QtGui.QApplication(sys.argv)
    window =  GalleryUi(imgLst)
    window.raise_()
    sys.exit(app.exec_())

if __name__ == '__main__':
    current_path = os.getcwd()
    if len(sys.argv) > 1:
        current_path = sys.argv[1:]
    main(utils.ingestData(current_path))
10
demandé sur Ciasto piekarz 2014-01-05 10:15:03

2 réponses

QTableView a contextMenuEvent() événement, pour afficher un menu clic-droit:

  • Créer un QMenu dans ce cas
  • Ajouter quelques QActions QMenu
  • se connecter QAction pour les fentes à l'aide de triggered signal de QAction
  • appel popup(QCursor.pos())QMenu

lorsque l'utilisateur fait un clic droit sur le tableView, la cellule sous le pointeur de la souris est sélectionnée et en même temps un menu apparaît. Lorsque l'utilisateur sélectionne une action sur le menu, la fente connectée sera appelée, obtenir la cellule sélectionnée de tabel dans cette fente et effectuer l'action requise sur cette cellule.

...
def contextMenuEvent(self, event):
    self.menu = QtGui.QMenu(self)
    renameAction = QtGui.QAction('Rename', self)
    renameAction.triggered.connect(lambda: self.renameSlot(event))
    self.menu.addAction(renameAction)
    # add other required actions
    self.menu.popup(QtGui.QCursor.pos())
    ...

def renameSlot(self, event):
    print "renaming slot called"
    # get the selected row and column
    row = self.tableWidget.rowAt(event.pos().y())
    col = self.tableWidget.columnAt(event.pos().x())
    # get the selected cell
    cell = self.tableWidget.item(row, col)
    # get the text inside selected cell (if any)
    cellText = cell.text()
    # get the widget inside selected cell (if any)
    widget = self.tableWidget.cellWidget(row, col)
...
18
répondu qurban 2016-12-05 08:38:43

Je l'ai finalement implémenté de cette façon!!

def contextMenuEvent(self, pos):
    if self.selectionModel().selection().indexes():
        for i in self.selectionModel().selection().indexes():
            row, column = i.row(), i.column()
        menu = QtGui.QMenu()
        openAction = menu.addAction("Open")
        deleAction = menu.addAction("Delete")
        renaAction = menu.addAction("Rename")
        action = menu.exec_(self.mapToGlobal(pos))
        if action ==openAction:
            self.openAction(row, column)

def openAction(self, row, column):
    if self._slideShowWin:
        self._slideShowWin.showImageByPath(self._twoDLst[row][column])
        self._animateUpOpen()

def deleteSelected(self):
    # TODO
    pass

qui fonctionne comme un charme !!!

3
répondu Ciasto piekarz 2014-11-19 05:17:20