mouseClickEvent is in ViewBoxCustom.py
and is correctly triggered when you click the scene. compute_spc_map
is in SPCanalyse.py
and ViewBoxCustom.py
doesn't import it as that would make a cyclic import. I know it can be done, but I want to avoid it.
snippet from ViewBoxCustom
from SPCanalyse import MainWindow #This import should not exist
def mouseClickEvent(self, ev):
elif ev.button() == QtCore.Qt.LeftButton:
ev.accept()
# The following line does not work because MainWindow is **NOT** imported
MainWindow.compute_spc_map(ev.pos().x(), ev.pos().y())
snippet from SPCanalyse
. SPCanalyse
imports ViewBoxCustom
so as to access functions and generate app functionality
from ViewBoxCustom import MultiRoiViewBox # MultiRoiViewBox contains mouseClickEvent
def compute_spc_map(self, x, y):
if not self.preprocessed_frames == None:
self.image = fj.get_correlation_map(y, x, self.preprocessed_frames)
I cant just place compute_spc_map
in ViewBoxCustom
because preprocessed_frames
is a variable generated and used in SPCanalyse
I thought it might work to connect the mouseClickEvent
in ViewBoxCustom
with compute_spc_map
in SPCanalyse
doing the following in SPCanalyse
from ViewBoxCustom import MultiRoiViewBox
self.vb = MultiRoiViewBox(lockAspect=True,enableMenu=True)
self.vb.mouseClickEvent.connect(self.compute_spc_map)
sadly mouseClickEvent
has no attribute 'connect'
It looks like you're trying to call a method on a parent widget from a child widget (ie. ViewBoxCustom
is a child of MainWindow
). You generally don't want to do this as it limits the flexibility of the child widget and can lead to circular dependencies like you have here when there's no reason the child should have to depend on the parent.
A good design pattern to use here is for the child to emit a Signal
, which the parent connects to, and uses it to trigger the calling of a function (as opposed to the child widget calling the function directly).
In your case:
class ViewBoxCustom(...)
clicked = QtCore.pyqtSignal(int, int)
def mouseClickEvent(self, ev):
if ev.button() == QtCore.Qt.LeftButton:
ev.accept()
self.clicked.emit(ev.pos().x(), ev.pos().y())
class MainWindow(QtGui.QMainWindow):
def __init__(...)
...
self.vbc = ViewBoxCustom(...)
self.vbc.clicked.connect(self.on_vbc_clicked)
@QtCore.pyqtSlot(int, int)
def on_vbc_clicked(self, x, y):
self.compute_spec_map(x, y)
There's no reason for ViewBoxCustom
to ever import or know anything about MainWindow
.