将继承的 mixin 方法装饰为 pyqtSlot
Decorating a inherited mixin method as a pyqtSlot
我有一个 LogMixIn class。我想创建一个 Logger class,我可以将其公开给 QML 供我的 QML 使用。由于我想使用的所有方法都来自 LogMixIn,有没有一种方法可以装饰继承的方法,而不是像我在下面的示例中那样重新定义它们?
my_logging_lib.py
class LogMixIn():
def logDebug(self, msg):
# Log msg at Debug Severity
qml_logger.py
from PyQt5.QtCore import QObject, pyqtSlot
from my_logging_lib import LogMixIn
class QmlLogger(QObject, LogMixIn):
@pyqtSlot(str)
def logDebug(self, msg):
super().logDebug(msg)
注 1: LogMixIn 用于大部分非 UI 代码,因此最好使其与 QT 无关。
在PyQt5中,pyqtSlot
可以修饰不继承自QObject
的classes的方法,比如普通的[=37] =] 混入 classes。您可以通过检查继承了这样一个 mixin 的 subclass 的 meta-object 来轻松地检查这一点:
from PyQt5.QtCore import pyqtSlot, QObject, QMetaMethod
class LogMixIn:
def logDebug(self, msg):
pass
@pyqtSlot(str)
def logDebugEx(self, msg):
pass
class QmlLogger(QObject, LogMixIn):
@pyqtSlot(str)
def logDebug(self, msg):
super().logDebug(msg)
foo = QmlLogger()
meta = foo.metaObject()
for index in range(meta.methodCount()):
method = meta.method(index)
if method.methodType() == QMetaMethod.Slot:
print(method.methodSignature())
输出:
b'deleteLater()'
b'_q_reregisterTimers(void*)'
b'logDebug(QString)'
b'logDebugEx(QString)'
如您所见,插槽的定义方式没有区别。这是因为在建立实际连接之前,PyQt 不需要检查包含 class 的类型。如果当时发现接收者是一个QObject
,PyQt 可以创建一个内部代理QObject
,其中有一个槽可以被Qt 使用。对于 QML,唯一重要的是这些方法可以通过元对象系统访问,以便可以通过例如调用它们。 invokeMethod.
请注意,pyqtSignal
和 pyqtProperty
也可以在混入中使用。但是,此行为仅在 PyQt5 中引入,因此在 PyQt4 中根本不起作用。不过,我相信在所有版本的 PySide 中都会发现类似的行为。
更新:
如果不能直接修饰 mixin,可以在 subclass 定义中创建插槽,如下所示:
class QmlLogger(QObject, LogMixIn):
logDebug = pyqtSlot(str)(LogMixIn.logDebug)
我有一个 LogMixIn class。我想创建一个 Logger class,我可以将其公开给 QML 供我的 QML 使用。由于我想使用的所有方法都来自 LogMixIn,有没有一种方法可以装饰继承的方法,而不是像我在下面的示例中那样重新定义它们?
my_logging_lib.py
class LogMixIn():
def logDebug(self, msg):
# Log msg at Debug Severity
qml_logger.py
from PyQt5.QtCore import QObject, pyqtSlot
from my_logging_lib import LogMixIn
class QmlLogger(QObject, LogMixIn):
@pyqtSlot(str)
def logDebug(self, msg):
super().logDebug(msg)
注 1: LogMixIn 用于大部分非 UI 代码,因此最好使其与 QT 无关。
在PyQt5中,pyqtSlot
可以修饰不继承自QObject
的classes的方法,比如普通的[=37] =] 混入 classes。您可以通过检查继承了这样一个 mixin 的 subclass 的 meta-object 来轻松地检查这一点:
from PyQt5.QtCore import pyqtSlot, QObject, QMetaMethod
class LogMixIn:
def logDebug(self, msg):
pass
@pyqtSlot(str)
def logDebugEx(self, msg):
pass
class QmlLogger(QObject, LogMixIn):
@pyqtSlot(str)
def logDebug(self, msg):
super().logDebug(msg)
foo = QmlLogger()
meta = foo.metaObject()
for index in range(meta.methodCount()):
method = meta.method(index)
if method.methodType() == QMetaMethod.Slot:
print(method.methodSignature())
输出:
b'deleteLater()'
b'_q_reregisterTimers(void*)'
b'logDebug(QString)'
b'logDebugEx(QString)'
如您所见,插槽的定义方式没有区别。这是因为在建立实际连接之前,PyQt 不需要检查包含 class 的类型。如果当时发现接收者是一个QObject
,PyQt 可以创建一个内部代理QObject
,其中有一个槽可以被Qt 使用。对于 QML,唯一重要的是这些方法可以通过元对象系统访问,以便可以通过例如调用它们。 invokeMethod.
请注意,pyqtSignal
和 pyqtProperty
也可以在混入中使用。但是,此行为仅在 PyQt5 中引入,因此在 PyQt4 中根本不起作用。不过,我相信在所有版本的 PySide 中都会发现类似的行为。
更新:
如果不能直接修饰 mixin,可以在 subclass 定义中创建插槽,如下所示:
class QmlLogger(QObject, LogMixIn):
logDebug = pyqtSlot(str)(LogMixIn.logDebug)