Контекстное меню на PySide2
В GUI при нажатии правой кнопкой мыши на таблицу, вызывается контекстное меню. Но проблема, что после этого это контекстное меню можно вызвать не только в таблице, но и в любом месте GUI, не смотря на виджет.
Как это исправить? Мне нужно вызывать конкретное меню на конкретной таблице. И нигде больше.
Привожу простой пример GUI, где ошибка четко воспроизводится
app.py
import sys
from PySide2 import QtWidgets
from UI_test import Ui_Form
from PySide2 import QtWidgets, QtGui, QtCore
class App(QtWidgets.QWidget):
def __init__(self, parent = None):
QtWidgets.QWidget.__init__(self, parent)
self.ui = Ui_Form()
self.ui.setupUi(self)
def contextMenuEvent(self,e):
#создание и вызов контекстного меню
self.menu = QtWidgets.QMenu(self)
Action1 = QtWidgets.QAction('Action1', self)
Action2 = QtWidgets.QAction('Action2', self)
Action3 = QtWidgets.QAction('Action3', self)
self.menu.addAction(Action1)
self.menu.addAction(Action2)
self.menu.addAction(Action3)
self.menu.popup(QtGui.QCursor.pos())
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
window = App()
window.show()
sys.exit(app.exec_())
UI_test.py
from PySide2 import QtCore, QtGui, QtWidgets
from PySide2.QtCore import Qt
from random import randint
class Ui_Form(object):
def setupUi(self, Form):
Form.resize(1300, 700)
self.layout = QtWidgets.QHBoxLayout()
self.layout.setContentsMargins(0, 0, 0, 0)
self.listWidget = QtWidgets.QListWidget()
self.layout.addWidget(self.listWidget)
self.stackedWidget = QtWidgets.QStackedWidget()
self.layout.addWidget(self.stackedWidget)
self.listWidget.currentRowChanged.connect(
self.stackedWidget.setCurrentIndex)
item1 = QtWidgets.QListWidgetItem(QtGui.QIcon('icons/settings.png'),'CamSettings', self.listWidget)
item2 = QtWidgets.QListWidgetItem(QtGui.QIcon('icons/explore.png'),'Explore', self.listWidget)
item1.setSizeHint(QtCore.QSize(10, 60))
item2.setSizeHint(QtCore.QSize(10, 60))
item1.setTextAlignment(QtCore.Qt.AlignCenter)
item2.setTextAlignment(QtCore.Qt.AlignCenter)
label1 = QtWidgets.QLabel('Это страница 1')
label2= QtWidgets.QLabel('Это страница 2')
label1.setAlignment(QtCore.Qt.AlignCenter)
label2.setAlignment(QtCore.Qt.AlignCenter)
label1.setStyleSheet('background: rgb(%d, %d, %d); margin: 50px;' % (
randint(0, 255), randint(0, 255), randint(0, 255)))
label2.setStyleSheet('background: rgb(%d, %d, %d); margin: 50px;' % (
randint(0, 255), randint(0, 255), randint(0, 255)))
self.table_cubes = QtWidgets.QTableWidget()
self.table_cubes.setColumnCount(1)
self.table_cubes.setObjectName('tableCubes')
self.table_cubes.setHorizontalHeaderLabels(['Название куба'])
header_class = self.table_cubes.horizontalHeader()
header_class.hide()
header_v_cube = self.table_cubes.verticalHeader()
header_v_cube.setStyleSheet(' background-color: #232939;')
self.table_cubes.setFixedWidth(310)
self.table_cubes.setFixedHeight(330)
self.table_cubes.setColumnWidth(0, 200)
self.table_cubes.contextMenuEvent = Form.contextMenuEvent
first_panel_left = QtWidgets.QVBoxLayout()
first_panel_left.setAlignment(Qt.AlignTop)
first_panel_frame_left = QtWidgets.QFrame()
first_panel_frame_left.setMinimumWidth(200)
first_panel_frame_left.setLayout(first_panel_left)
first_panel_right = QtWidgets.QVBoxLayout()
first_panel_right.addWidget(self.table_cubes)
first_panel_right.addStretch()
first_panel_frame_right = QtWidgets.QFrame()
first_panel_frame_right.setLayout(first_panel_right)
main_first_box = QtWidgets.QHBoxLayout()
main_first_box.addWidget(first_panel_frame_left)
main_first_box.addWidget(first_panel_frame_right)
first_container = QtWidgets.QWidget()
first_container.setLayout(main_first_box)
self.stackedWidget.addWidget(first_container)
self.stackedWidget.addWidget(label2)
Form.setLayout(self.layout)
Ответы (1 шт):
Автор решения: S. Nick
→ Ссылка
Как вариант
import sys
from random import randint
'''
from PySide2 import QtCore, QtGui, QtWidgets
from PySide2.QtCore import Qt
'''
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.Qt import *
#from UI_test import Ui_Form
class Ui_Form(object):
def setupUi(self, Form):
Form.resize(800, 500)
self.layout = QtWidgets.QHBoxLayout()
self.layout.setContentsMargins(0, 0, 0, 0)
self.listWidget = QtWidgets.QListWidget()
self.layout.addWidget(self.listWidget)
self.stackedWidget = QtWidgets.QStackedWidget()
self.layout.addWidget(self.stackedWidget)
self.listWidget.currentRowChanged.connect(
self.stackedWidget.setCurrentIndex)
item1 = QtWidgets.QListWidgetItem(QtGui.QIcon('Ok.png'),'CamSettings', self.listWidget)
item2 = QtWidgets.QListWidgetItem(QtGui.QIcon('im.png'),'Explore', self.listWidget)
item1.setSizeHint(QtCore.QSize(10, 60))
item2.setSizeHint(QtCore.QSize(10, 60))
item1.setTextAlignment(QtCore.Qt.AlignCenter)
item2.setTextAlignment(QtCore.Qt.AlignCenter)
label1 = QtWidgets.QLabel('Это страница 1')
label2= QtWidgets.QLabel('Это страница 2')
label1.setAlignment(QtCore.Qt.AlignCenter)
label2.setAlignment(QtCore.Qt.AlignCenter)
label1.setStyleSheet('background: rgb(%d, %d, %d); margin: 50px;' % (
randint(0, 255), randint(0, 255), randint(0, 255)))
label2.setStyleSheet('background: rgb(%d, %d, %d); margin: 50px;' % (
randint(0, 255), randint(0, 255), randint(0, 255)))
self.table_cubes = QtWidgets.QTableWidget()
self.table_cubes.setColumnCount(1)
self.table_cubes.setObjectName('tableCubes')
self.table_cubes.setHorizontalHeaderLabels(['Название куба'])
header_class = self.table_cubes.horizontalHeader()
header_class.hide()
header_v_cube = self.table_cubes.verticalHeader()
header_v_cube.setStyleSheet(' background-color: #232939;')
self.table_cubes.setFixedWidth(310)
self.table_cubes.setFixedHeight(330)
self.table_cubes.setColumnWidth(0, 200)
# - self.table_cubes.contextMenuEvent = Form.contextMenuEvent
first_panel_left = QtWidgets.QVBoxLayout()
first_panel_left.setAlignment(Qt.AlignTop)
first_panel_frame_left = QtWidgets.QFrame()
first_panel_frame_left.setMinimumWidth(200)
first_panel_frame_left.setLayout(first_panel_left)
first_panel_right = QtWidgets.QVBoxLayout()
first_panel_right.addWidget(self.table_cubes)
first_panel_right.addStretch()
first_panel_frame_right = QtWidgets.QFrame()
first_panel_frame_right.setLayout(first_panel_right)
main_first_box = QtWidgets.QHBoxLayout()
main_first_box.addWidget(first_panel_frame_left)
main_first_box.addWidget(first_panel_frame_right)
first_container = QtWidgets.QWidget()
first_container.setLayout(main_first_box)
self.stackedWidget.addWidget(first_container)
self.stackedWidget.addWidget(label2)
Form.setLayout(self.layout)
class App(QtWidgets.QWidget):
def __init__(self, parent = None):
QtWidgets.QWidget.__init__(self, parent)
self.ui = Ui_Form()
self.ui.setupUi(self)
# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
self.item = None
self.ui.table_cubes.installEventFilter(self) # !!!
self.ui.table_cubes.setRowCount(3)
self.ui.table_cubes.setItem(0, 0, QtWidgets.QTableWidgetItem('Hello'))
self.ui.table_cubes.setItem(2, 0, QtWidgets.QTableWidgetItem('World'))
def eventFilter(self, source, event):
if event.type() == QEvent.ContextMenu and source is self.ui.table_cubes:
menu = QMenu()
menu.addAction('Action 1')
menu.addAction('Action 2')
menu.addAction('Action 3')
menu.triggered.connect(self.selected)
if menu.exec_(event.globalPos()):
self.item = source.itemAt(event.pos())
return True
return super().eventFilter(source, event)
def selected(self, q):
self.q = q.text()
QTimer.singleShot(10, lambda: print(f'{self.item.text() if self.item else None}: {self.q}'))
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
window = App()
window.show()
sys.exit(app.exec_())
