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))
2 réponses
QTableView
a contextMenuEvent()
événement, pour afficher un menu clic-droit:
- Créer un
QMenu
dans ce cas - Ajouter quelques
QAction
sQMenu
- se connecter
QAction
pour les fentes à l'aide detriggered
signal deQAction
- 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)
...
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 !!!