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 中,您正在覆盖 QPushButton
的 mousePressEvent
方法,而没有使用 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)
我正在尝试在信号和槽之间创建一个简单的连接,但发现自己无法调用额外的函数。我有两种选择。这是调用我的 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 中,您正在覆盖 QPushButton
的 mousePressEvent
方法,而没有使用 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)