This is really more of a IT/ PyQt question, so I will provide an answer in the context of QGIS plugin development, to try to keep on topic.
The reason your mousePressEvent
does nothing is that you have defined it inside your main plugin class. The mousePressEvent
method is designed to be re-implemented inside a sub class which inherits from one of the QWidget
abstract base classes, in this case QGraphicsView
.
You need to create a new class in your main plugin python file which sub-classes QGraphicsView
and re-implements the mousePressEvent()
method. Then create an instance of your subclass and add it to a layout of your dock widget.
I created a simple plugin, based on your ui
file which just adds the dock widget to the QGIS main window, catches a mouse click event in the graphics view and pushes a message to the message bar showing which mouse button was clicked.
I modified your ui
file by deleting the QGraphicsView
object, so we can create an instance of our custom subclass in the __init__()
method. Then, inside the initGui()
method, we set its parent to the dock widget, and add it to the horizontalLayout_2
object.
the ui xml file looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>qgisSpectreDockWidgetBase</class>
<widget class="QDockWidget" name="qgisSpectreDockWidgetBase">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>564</width>
<height>321</height>
</rect>
</property>
<property name="windowTitle">
<string>Spectre &Viewer</string>
</property>
<widget class="QWidget" name="dockWidgetContents">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="1" column="0">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QComboBox" name="cbLayer"/>
</item>
<item>
<widget class="QComboBox" name="cbItem"/>
</item>
</layout>
</item>
<item row="2" column="0">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<layout class="QVBoxLayout" name="verticalLayout"/>
</item>
<item>
<widget class="QPushButton" name="pBCopy">
<property name="text">
<string>Copy</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections/>
</ui>
the contents of the plugin dialog python file:
import os
from PyQt5 import uic
from PyQt5 import QtWidgets
FORM_CLASS, _ = uic.loadUiType(os.path.join(
os.path.dirname(__file__), 'dock_widget_example_dialog_base.ui'))
class DockWidgetExampleDialog(QtWidgets.QDockWidget, FORM_CLASS):
def __init__(self, parent=None):
super(DockWidgetExampleDialog, self).__init__(parent)
self.setupUi(self)
And finally, the main plugin python file:
from PyQt5.QtCore import QSettings, QTranslator, qVersion, QCoreApplication, Qt
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QAction, QGraphicsView
from .resources import *
from .dock_widget_example_dialog import DockWidgetExampleDialog
import os.path
class DockWidgetExample:
"""QGIS Plugin Implementation."""
def __init__(self, iface):
# Save reference to the QGIS interface
self.iface = iface
# initialize plugin directory
self.plugin_dir = os.path.dirname(__file__)
# initialize locale
locale = QSettings().value('locale/userLocale')[0:2]
locale_path = os.path.join(
self.plugin_dir,
'i18n',
'DockWidgetExample_{}.qm'.format(locale))
if os.path.exists(locale_path):
self.translator = QTranslator()
self.translator.load(locale_path)
if qVersion() > '4.3.3':
QCoreApplication.installTranslator(self.translator)
# Create the dialog (after translation) and keep reference
self.dlg = DockWidgetExampleDialog(self.iface.mainWindow())
# Declare instance attributes
self.view = My_Graphics_View(self.iface)
self.actions = []
self.menu = self.tr(u'&Dockwidget Example')
# TODO: We are going to let the user set this up in a future iteration
self.toolbar = self.iface.addToolBar(u'DockWidgetExample')
self.toolbar.setObjectName(u'DockWidgetExample')
# noinspection PyMethodMayBeStatic
def tr(self, message):
# noinspection PyTypeChecker,PyArgumentList,PyCallByClass
return QCoreApplication.translate('DockWidgetExample', message)
def add_action(
self,
icon_path,
text,
callback,
enabled_flag=True,
add_to_menu=True,
add_to_toolbar=True,
status_tip=None,
whats_this=None,
parent=None):
icon = QIcon(icon_path)
action = QAction(icon, text, parent)
action.triggered.connect(callback)
action.setEnabled(enabled_flag)
if status_tip is not None:
action.setStatusTip(status_tip)
if whats_this is not None:
action.setWhatsThis(whats_this)
if add_to_toolbar:
self.toolbar.addAction(action)
if add_to_menu:
self.iface.addPluginToMenu(
self.menu,
action)
self.actions.append(action)
return action
def initGui(self):
"""Create the menu entries and toolbar icons inside the QGIS GUI."""
icon_path = ':/plugins/dock_widget_example/icon.png'
self.add_action(
icon_path,
text=self.tr(u'Add a Dock Widget'),
callback=self.run,
parent=self.iface.mainWindow())
self.view.setParent(self.dlg)
self.dlg.horizontalLayout_2.addWidget(self.view)
def unload(self):
"""Removes the plugin menu item and icon from QGIS GUI."""
for action in self.actions:
self.iface.removePluginMenu(
self.tr(u'&Dockwidget Example'),
action)
self.iface.removeToolBarIcon(action)
# remove the toolbar
del self.toolbar
def run(self):
self.iface.mainWindow().addDockWidget(Qt.BottomDockWidgetArea, self.dlg)
self.dlg.show()
class My_Graphics_View(QGraphicsView):
def __init__(self, iface):
self.iface = iface
QGraphicsView.__init__(self)
def mousePressEvent(self, event):
if event.button() == 1:
self.iface.messageBar().pushMessage('Left click')
elif event.button() == 2:
self.iface.messageBar().pushMessage('Right click')
The result: after launching the plugin with the icon or from the menu item and clicking inside the QGraphicsView widget, we get a message about which button was clicked pushed to the message bar:

By the way, I would recommend keeping signal/ slot connections out of the run()
method and putting them in the initGui()
method instead.