PyQt5 记录一个信号

PyQt5 log a signal

我正在尝试在信号和槽之间创建一个简单的连接,但发现自己无法调用额外的函数。我有两种选择。这是调用我的 class 的代码。

(选项 1):

self.flip = MyClass("Flip Image")
self.flip.clicked.connect(self.do_flip)

QWidget 然后由我的 class 实例化,其主要目的是记录发出的信号。这就是我认为我的 class 应该实施的方式:

class MyClass(QPushButton):

    def __init__(self, name: str) -> None:
        super().__init__(name)
        self._name = name

    def mousePressEvent(self, *args, **kwargs):
        self.log_info()

    def log_info(self):
        log(self._name)

我不明白的是为什么 do_flip 槽从来没有被调用过?这对我来说毫无意义,所以我改为尝试通过

覆盖点击信号

(选项 2):

class MyClass(QPushButton):

    def __init__(self, name: str) -> None:
        super().__init__(name)
        self._name = name

    def clicked(self, *args, **kwargs):
        self.log_info()
        #add connect() here?

    def log_info(self):
        log(self._name)

但是使用这段代码我得到了一个友好的AttributeError: 'function' object has no attribute 'connect'。我找不到有关 clicked 方法及其调用连接方式的任何文档。有没有办法让我连接到插槽,或者我必须创建自己的信号?我发现这在尝试覆盖也发出特定值的其他信号时会变得非常有用。

如果是这样,这会引导我:

不得已 - 我自己的信号

class 会这样调用:

self.flip = MyClass("Flip Image")
self.flip.mysig.connect(self.do_flip)

并这样实现:

class MyClass(QPushButton):

    mysig = pyqtSignal()

    def __init__(self, name: str) -> None:
        super().__init__(name)
        self._name = name

    def mousePressEvent(self, *args, **kwargs):
        self.mysig.emit()
        self.log_info()

    def log_info(self):
        log(self._name)

这行得通。但我不确定我的实施是否有意义。感觉有点hacky。我不想使用这个最后的选择,我希望有一个更干净的选择。

选项 1 中,您正在覆盖 QPushButtonmousePressEvent 方法,而没有使用 super 调用默认实现,我相信这一点是 clicked 信号从未发出的原因。例如:

class MyClass(QPushButton):

def __init__(self, name: str) -> None:
    super().__init__(name)
    self._name = name

def mousePressEvent(self, event):
    self.log_info()
    super().mousePressEvent(event)

def log_info(self):
    log(self._name)

选项 2 中,您将 clicked 声明为正常的 python 可调用,而它应该是 pyqtSignal()。这也绝对不是要走的路。

实现您需要的正确方法是对同一信号使用多个插槽,即:

class MyClass(QPushButton):

    def __init__(self, name: str) -> None:
        super().__init__(name)
        self._name = name

    @pyqtSlot()
    def log_info(self):
        log(self._name)

self.flip = MyClass("Flip Image")
self.flip.clicked.connect(self.do_flip)
self.flip.clicked.connect(self.flip.log_info)