как добавить контекстное меню к каждой ячейке лист в PyQt
Я хочу добавить меню щелчка правой кнопкой мыши для удаления, переименования или открытия изображения в каждой ячейке QTAbleView в меню щелчка rigt, я пробовал и нашел, что все пытаются добавить меню в заголовок в 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 ответов
QTableView
и contextMenuEvent()
событие, чтобы показать контекстное меню:
- создать
QMenu
внутри этого события - добавить
QAction
s доQMenu
- подключение каждого
QAction
в слоты с помощьюtriggered
сигналQAction
- вызов
popup(QCursor.pos())
onQMenu
когда пользователь щелкните правой кнопкой мыши 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)
...
Я, наконец, реализовал его таким образом!!
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
это работает как шарм !!!