Issue
How do I subclass the QListView's doubleclick item and contextmenu event?
In my case I want to subclass QListview and when the user doubleclicks and item, i would like the to print the data (display role text) of the double clicked item.
Secondly i would like to build the context menu into the QListView. I'm not sure how to properly have it display where the user right-clicks.
class MyListView(QtGui.QListView):
def __init__(self, *args, **kwargs):
QtGui.QListView.__init__(self, *args, **kwargs)
self.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
self.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
self.setViewMode(QtGui.QListView.IconMode)
self.setResizeMode(QtGui.QListView.Adjust)
self.setMovement(QtGui.QListView.Static)
self.setSpacing(5)
self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
# self.customContextMenuRequested.connect(self.open_tags_list_menu)
self.setStyleSheet('''
QListView::item {
border: 1px solid rgba(0,0,0,60);
background: rgba(0,0,0,30);
border-radius: 2px;
}
QListView::item:selected {
border: 1px solid rgba(70,150,255,255);
background: rgba(70,150,255,200);
border-radius: 2px;
}
''')
self.act_delete_selected = QtGui.QAction('Delete Selected', self)
self.act_delete_all = QtGui.QAction('Delete All', self)
self.my_menu = QtGui.QMenu()
self.my_menu.addAction(self.act_delete_selected)
self.my_menu.addAction(self.act_delete_all)
def mouseDoubleClickEvent(self, event):
if event.button() == QtCore.Qt.LeftButton:
print 'text of item clickd'
QtGui.QListView.mouseDoubleClickEvent(self, event)
def onCustomContextMenuRequested(self, point):
print 'my_menu'
Solution
To obtain the data you need the QModelIndex
, as we have the position event.pos()
, you must use itemAt()
:
def mouseDoubleClickEvent(self, event):
if event.button() == QtCore.Qt.LeftButton:
ix = self.indexAt(event.pos())
print(ix.data())
QtGui.QListView.mouseDoubleClickEvent(self, event)
The customContextMenuRequested
signal must be connected to a slot, it provides the position information, it is used to tell you where the menu should be displayed, exec_()
returns the selected QAction
:
self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.customContextMenuRequested.connect(self.onCustomContextMenuRequested)
def onCustomContextMenuRequested(self, point):
my_menu = QtGui.QMenu(self)
act_delete_selected = QtGui.QAction('Delete Selected', self)
act_delete_all = QtGui.QAction('Delete All', self)
my_menu.addAction(act_delete_selected)
my_menu.addAction(act_delete_all)
action = my_menu.exec_(self.mapToGlobal(point))
if action == act_delete_selected:
[some code]
elif action == act_delete_all:
self.model().removeRows(0, self.model().rowCount())
Example:
from PySide import QtGui, QtCore
class MyListView(QtGui.QListView):
def __init__(self, *args, **kwargs):
QtGui.QListView.__init__(self, *args, **kwargs)
self.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
self.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
self.setViewMode(QtGui.QListView.IconMode)
self.setResizeMode(QtGui.QListView.Adjust)
self.setMovement(QtGui.QListView.Static)
self.setSpacing(5)
self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.customContextMenuRequested.connect(self.onCustomContextMenuRequested)
self.setStyleSheet('''
QListView::item {
border: 1px solid rgba(0,0,0,60);
background: rgba(0,0,0,30);
border-radius: 2px;
}
QListView::item:selected {
border: 1px solid rgba(70,150,255,255);
background: rgba(70,150,255,200);
border-radius: 2px;
}
''')
def mouseDoubleClickEvent(self, event):
if event.button() == QtCore.Qt.LeftButton:
ix = self.indexAt(event.pos())
print(ix.data())
QtGui.QListView.mouseDoubleClickEvent(self, event)
def onCustomContextMenuRequested(self, point):
my_menu = QtGui.QMenu(self)
act_delete_selected = QtGui.QAction('Delete Selected', self)
act_delete_all = QtGui.QAction('Delete All', self)
my_menu.addAction(act_delete_selected)
my_menu.addAction(act_delete_all)
action = my_menu.exec_(self.mapToGlobal(point))
if action == act_delete_selected:
for ix in self.selectedIndexes():
self.model().removeRows(ix.row(), 1)
self.clearSelection()
elif action == act_delete_all:
self.model().removeRows(0, self.model().rowCount())
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
w = MyListView()
model = QtGui.QStringListModel([str(i) for i in range(100)])
w.setModel(model)
w.show()
sys.exit(app.exec_())
Answered By - eyllanesc
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.