如何子类化QListView doubleclick和contextmenu

时间:2017-12-13 01:08:49

标签: python pyside

如何对QListView的双击项和contextmenu事件进行子类化?

在我的情况下,我想要子类化QListview,当用户双击和项目时,我希望打印双击项目的数据(显示角色文本)。

其次我想在QListView中构建上下文菜单。我不确定如何正确显示用户右键单击的位置。

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'

1 个答案:

答案 0 :(得分:1)

要获取您需要QModelIndex的数据,因为我们的位置为event.pos(),您必须使用itemAt()

def mouseDoubleClickEvent(self, event):
    if event.button() == QtCore.Qt.LeftButton:
        ix = self.indexAt(event.pos())
        print(ix.data())
    QtGui.QListView.mouseDoubleClickEvent(self, event)

customContextMenuRequested信号必须连接到一个插槽,它提供位置信息,用于告诉您应该显示菜单的位置,exec_()返回选定的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())

示例:

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