当一个模块有信号而另一个模块有槽和参数需要传递时避免循环导入

Avoiding a circular import when one module has the signal and another the slot and arguments need to be passed

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,但我想避免它。

来自 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())

来自 SPCanalyse 的片段。 SPCanalyse 导入 ViewBoxCustom 以便访问函数和生成应用程序功能

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)

我不能只将 compute_spc_map 放在 ViewBoxCustom 中,因为 preprocessed_frames 是在 SPCanalyse

中生成和使用的变量

我认为将 ViewBoxCustom 中的 mouseClickEventSPCanalyse 中的 compute_spc_map 连接起来可能会起作用,在 SPCanalyse

中执行以下操作
from ViewBoxCustom import MultiRoiViewBox
self.vb = MultiRoiViewBox(lockAspect=True,enableMenu=True)
self.vb.mouseClickEvent.connect(self.compute_spc_map)

很遗憾mouseClickEvent没有属性'connect'

您似乎在尝试从子窗口小部件(即 ViewBoxCustomMainWindow 的子窗口小部件)调用父窗口小部件的方法。您通常不想这样做,因为它限制了子窗口小部件的灵活性,并且可能导致循环依赖,就像您在此处看到的那样,当子窗口没有理由必须依赖父窗口时。

这里使用的一个好的设计模式是让子部件发出一个 Signal,父部件连接到它,并使用它来触发函数调用(与子部件调用直接运行)。

你的情况:

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)

ViewBoxCustom 没有理由导入或了解 MainWindow