Hello World / plɹoM ollǝH

Programmers Live in Vain

PySide: Suppress the clicked signal when emitting a contextMenuRequested signal

右クリックでコンテキストメニューを出すときに一緒にclickedシグナルが発信されると困るケースがあった。mousePressEventとmouseReleaseEventを継承して左クリックのみに反応するようにしてこれを回避した

from PySide import QtGui, QtCore
import sys


class CustomListWidget(QtGui.QListWidget):
    def __init__(self):
        super().__init__()
        self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.clicked.connect(lambda: print('clicked'))
        self.customContextMenuRequested.connect(self._showContextMenu)
        self.addItem(QtGui.QListWidgetItem('hoge'))
        self.addItem(QtGui.QListWidgetItem('fuga'))
        self.addItem(QtGui.QListWidgetItem('piyo'))

    def mousePressEvent(self, event):
        # 左クリックのときだけ反応させる
        if event.button() == QtCore.Qt.LeftButton:
            super().mousePressEvent(event)

    def mouseReleaseEvent(self, event):
        # 選択状態のアイテムにはReleaseEventのフックも必要
        # 左クリックのときだけ反応させる
        if event.button() == QtCore.Qt.LeftButton:
            super().mouseReleaseEvent(event)

    def _showContextMenu(self, pos):
        item = self.itemAt(pos)
        if not item:
            return
        menu = QtGui.QMenu()
        menu.addAction(QtGui.QAction(item.text(), self))
        menu.exec_(self.mapToGlobal(pos))

app = QtGui.QApplication(sys.argv)
w = CustomListWidget()
w.show()
sys.exit(app.exec_())