如何在PyQt中为QTableView的每个单元格添加一个右键菜单

时间:2014-01-05 06:15:03

标签: python-2.7 pyqt contextmenu qtableview qtablewidgetitem

我想在严格点击菜单中添加一个右键菜单来删除,重命名或打开QTAbleView的每个单元格中的图像,我试过并发现每个人都试图将菜单添加到tableview中的标题,我试过下面但这似乎不适用于下面的代码..

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))

2 个答案:

答案 0 :(得分:19)

QTableViewcontextMenuEvent()个事件,以显示右键菜单:

  • 在此活动中创建QMenu
  • 将一些QAction添加到QMenu
  • 使用QAction
  • triggered信号将每个QAction连接到广告位
  • popup(QCursor.pos())
  • 上致电QMenu

当用户右键单击tableView时,将选择鼠标指针下的单元格,同时会出现一个菜单。当用户在菜单上选择一个动作时,将调用连接的插槽,在此插槽中获取所选的tabel单元格并对该单元格执行所需的操作。

...
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)
...

答案 1 :(得分:3)

我终于以这种方式实现了它!

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

就像魅力一样!!!