我可以想象,根据事件的不同,其中可能会有很多,但同时,我想这可能是调试的最佳方式,也是一个有趣的教训。
为什么我需要它?我正在使用一些基于 的自定义类,当我在同一窗口中QWidget
取消附加基于时,它不会扩展。QDockWidget
知道当这个停靠小部件被解除附加时会发出什么信号将帮助我选择我需要在我的自定义类中覆盖的方法。
换句话说,我不想检查文档中所有可能的信号,而只想查看在我的应用程序中执行某些操作时发出了哪些信号。
我可以想象,根据事件的不同,其中可能会有很多,但同时,我想这可能是调试的最佳方式,也是一个有趣的教训。
为什么我需要它?我正在使用一些基于 的自定义类,当我在同一窗口中QWidget
取消附加基于时,它不会扩展。QDockWidget
知道当这个停靠小部件被解除附加时会发出什么信号将帮助我选择我需要在我的自定义类中覆盖的方法。
换句话说,我不想检查文档中所有可能的信号,而只想查看在我的应用程序中执行某些操作时发出了哪些信号。
这对于任何公共 API 都是不可能的。
但是,如果您将代码放入基于 QTestLib 的单元测试中,您可以运行单元测试-vs
以打印出每个发出的信号。
您可能想看看QSignalSpy类。我认为尽管您必须手动连接要监视的信号。
我认为 Qt 不可能做到这一点。你可以
但在这之后我被困住了。我不认为,除了发送者之外,任何关于插槽如何被调用的信息都可以获得。
如果您使用的是 PyQT5 而不是 Qt5,则可以使用 Python 的自省功能来查找任何类的所有信号并将它们连接到(虚拟对象的)虚拟插槽。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from typing import Iterable
from PyQt5.QtCore import pyqtBoundSignal
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtCore import QObject
def list_all_signals(obj: QObject) -> Iterable[pyqtBoundSignal]:
attr_names = dir(obj)
attributes = (getattr(obj, attr_name) for attr_name in attr_names)
connectable = filter(lambda l: hasattr(l, "connect"), attributes)
return connectable
class SignalListener(QObject):
@pyqtSlot()
def universal_slot(self, *args, **kwargs):
print("Signal caught" + 30 * "-")
print("sender:", self.sender())
meta_method = (
self.sender().metaObject().method(self.senderSignalIndex())
)
print("signal:", meta_method.name())
print("signal signature:", meta_method.methodSignature())
SIGNAL_LISTENER = SignalListener()
def spy_on_all_signals(
obj: QObject, listener: SignalListener = SIGNAL_LISTENER
):
for signal in list_all_signals(obj):
signal.connect(SIGNAL_LISTENER.universal_slot)
虚拟插槽现在打印有关对象发出的所有信号的信息。例如,如果您像这样监视随机 QLineEdit:
some_line_edit = QLineEdit(self)
spy_on all_signals(some_line_edit)
进入和退出行编辑的可能日志可能如下所示:
Signal caught ------------------------------
sender: <PyQt5.QtWidgets.QLineEdit object at 0x7f220f7a3370>
signal: b'cursorPositionChanged'
signal signature: b'cursorPositionChanged(int,int)'
Signal caught ------------------------------
sender: <PyQt5.QtWidgets.QLineEdit object at 0x7f220f7a3370>
signal: b'selectionChanged'
signal signature: b'selectionChanged()'
Signal caught ------------------------------
sender: <PyQt5.QtWidgets.QLineEdit object at 0x7f220f7a3370>
signal: b'selectionChanged'
signal signature: b'selectionChanged()'
Signal caught ------------------------------
sender: <PyQt5.QtWidgets.QLineEdit object at 0x7f220f7a3370>
signal: b'editingFinished'
signal signature: b'editingFinished()'
检查信号间谍。深入了解 QT 库并监视信号/插槽。