22

我想在 rigt 单击菜单中的 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))
4

2 回答 2

32

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

  • QMenu在此事件中创建一个
  • 添加一些QActions到QMenu
  • 使用信号将每个连接QAction到插槽triggeredQAction
  • 打电话popup(QCursor.pos())_QMenu

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

...
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)
...
于 2014-01-05T07:33:08.850 回答
10

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

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

这就像一个魅力!

于 2014-01-05T11:08:43.787 回答