QListViewなどView系を使っていると、このViewに右クリックメニューを追加したい!っと思うことが多々あります。シンプルですが、こんな感じかと思います。
こんな風にできると、コピーや、削除といったことがやりやすくなりますねっ!(*´ω`*)
早速、QListViewをベースにご紹介したいと思います!(`・ω・´)ゞ
クラスの骨格
まずは、QListViewを継承したクラスを用意します。
from PySide import QtCore from PySide import QtGui class ListView(QtGui.QListView): def __init__(self, *args, **kwargs): super(ListView, self).__init__(*args, **kwargs)
右クリックメニューを追加する準備
QListViewなどに右クリックメニューを追加するポイントなのが「setContextMenuPolicy」です。PySide(Qt)では、右クリックメニューのことを「ContextMenu」と言います。
「setContextMenuPolicy」に「QtCore.Qt.CustomContextMenu」を設定すると「オリジナルのメニューを使うぜ!」っとなります。
from PySide import QtCore from PySide import QtGui class ListView(QtGui.QListView): def __init__(self, *args, **kwargs): super(ListView, self).__init__(*args, **kwargs) self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
次に、CustomContextMenuの処理を追加します。これはSignal&Slotで実装することができちゃいます(*´ω`*)
右クリックメニューのSignalは「customContextMenuRequested」になります。引数に、マウスの右クリックされた位置が渡されます。
from PySide import QtCore from PySide import QtGui class ListView(QtGui.QListView): def __init__(self, *args, **kwargs): super(ListView, self).__init__(*args, **kwargs) self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.contextMenu) def contextMenu(self, point): pass
右クリックメニューの実装
ここでは、for文を使って、簡単に5つのメニュー項目を作ります。QMenuのインスタンスを作り、addActionするのが簡単かと思います。メニューの作り方は通常のメニューづくりと同じです。
from PySide import QtCore from PySide import QtGui class ListView(QtGui.QListView): def __init__(self, *args, **kwargs): super(ListView, self).__init__(*args, **kwargs) self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu) self.customContextMenuRequested.connect(self.contextMenu) def contextMenu(self, point): menu = QtGui.QMenu(self) for i in range(5): action = QtGui.QAction('Menu%s' % i, self) menu.addAction(action) menu.exec_(self.mapToGlobal(point))
最後が今まで違うメニュー作りになります。
まず、QMenuの「exec_()」を実行しないと表示されません。。。その時に、表示する位置を指定するわけなのですが、引数で渡された位置「pos」は、座標がローカル空間?なので、位置がズレてしまいます。(;´∀`)
View系の「mapToGlobal」を使ってグローバル空間に変換すると位置がズレなくなります!
ちなみに、、、
「menu.exec_()」ではなく、「menu.show()」を使うと、表示する位置が思ったところに来ませんのでご注意ください(;´∀`)