コンテキストメニューを作る
いろいろな Widgets を作っていくと、右クリックメニューを作りたくなるかと思います。
今回は、PySide で右クリックメニューを作る方法を説明したいと思います。
コード
まずはコード。
# -*- coding: utf-8 -*-
import sys
from PySide2 import QtCore, QtGui, QtWidgets
class UISample(QtWidgets.QDialog):
def __init__(self, parent=None):
super(UISample, self).__init__(parent)
layout = QtWidgets.QVBoxLayout()
# カスタムUIを作成
self.list = QtWidgets.QTreeView()
layout.addWidget(self.list)
self.list2 = QtWidgets.QTreeView()
# List1で表示するContextMenuを設定
self.list.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.list.customContextMenuRequested.connect(self.listContext)
# List2で表示するContextMenuを指定
self.list2.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.list2.customContextMenuRequested.connect(self.list2Context)
layout.addWidget(self.list2)
# ここまでUI作成
self.setLayout(layout)
def listContext(self, pos):
menu = QtWidgets.QMenu(self.list)
action_01 = menu.addAction('ほげほげ')
action_01.triggered.connect(lambda: self.action('A'))
action_02 = menu.addAction('ふがふが')
action_02.triggered.connect(lambda: self.action('B'))
menu.addSeparator()
subMenu = menu.addMenu('SubMenu')
action_03 = subMenu.addAction('さぶめにゅー1')
action_03.triggered.connect(self.subMenu)
menu.exec_(self.list.mapToGlobal(pos))
def action(self, actionText):
print(actionText)
def subMenu(self):
print("SUBMENU")
def list2Context(self, pos):
menu = QtWidgets.QMenu(self.list2)
menu.addAction('list2_Menu')
menu.addAction('list2_Menu2')
menu.addAction('list2_Menu2')
menu.exec_(self.list2.mapToGlobal(pos))
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
a = UISample()
a.show()
sys.exit(app.exec_())
実行すると、こんな感じの UI が表示されます。
以下、詳しい解説。
Signal-Slot を作る
まず、メニューを表示したい場合は、PySide のお約束の 「Signal-Slot」 を作成します。
self.list.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
self.list.customContextMenuRequested.connect(self.listContext)
それがこの部分になります。
PySide では、右クリックで表示されるメニューのことを「コンテキストメニュー」と呼びます。
今回のように、自分でこのコンテキストメニューを作りたい場合は
Signal-Slot とは別に、setContexdtMenuPolicy で CustomContextMenu の設定をしておきます。
このフラグを ON にしたら、次にメニューを呼び出すためのシグナルを作成します。
このコンテキストメニューは、Widgets 単位で作成することができます。
ので、例えば今回のサンプルのように
2 つの ListView があった場合に、それぞれ別のメニューを表示出来るようにしたい場合
それぞれの Widgets ごとにこの ContextMenu の設定を行います。
def listContext(self, pos):
menu = QtWidgets.QMenu(self.list)
action_01 = menu.addAction('ほげほげ')
action_01.triggered.connect(lambda: self.action('A'))
action_02 = menu.addAction('ふがふが')
action_02.triggered.connect(lambda: self.action('B'))
menu.addSeparator()
subMenu = menu.addMenu('SubMenu')
action_03 = subMenu.addAction('さぶめにゅー1')
action_03.triggered.connect(self.subMenu)
menu.exec_(self.list.mapToGlobal(pos))
そんでもって、右クリックを押したときに呼ばれる関数を作成します。
単純に右クリックに割り当てただけだと、もちろんメニューは表示されません。
メニュー部分は QWidgets.QMneu クラスを使用します。
Menu を追加する
action_01 = menu.addAction('ほげほげ')
action_01.triggered.connect(lambda: self.action('A'))