【问题标题】:Decorating a inherited mixin method as a pyqtSlot将继承的 mixin 方法装饰为 pyqtSlot
【发布时间】:2019-08-07 14:11:12
【问题描述】:

我有一个 LogMixIn 类。我想创建一个 Logger 类,我可以向 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 无关。

【问题讨论】:

  • @eyllanesc,这是正确的。上面的实现工作正常,而且看起来是正确的,但从概念上讲,似乎还有另一种方法可以以一种干净、紧凑的方式来实现。

标签: python qml pyqt5 decorator slot


【解决方案1】:

在 PyQt5 中,pyqtSlot可以修饰不继承自 QObject 的类的方法,例如普通的 Python mixin 类。您可以通过检查继承此类 mixin 的子类的 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 在建立实际连接之前不需要检查包含类的类型。如果当时发现接收者是QObject,PyQt 可以创建一个内部代理QObject,带有一个Qt 可以使用的槽。对于 QML,唯一重要的是方法可以通过元对象系统访问,以便可以通过例如调用它们。 invokeMethod.

请注意,pyqtSignalpyqtProperty 也可以在 mixins 中使用。但是,这种行为仅在 PyQt5 中引入,因此在 PyQt4 中根本不起作用。不过,我相信在所有版本的 PySide 中都会发现类似的行为。

更新

如果你不能直接装饰 mixin,可以像这样在子类定义中创建槽:

class QmlLogger(QObject, LogMixIn):
    logDebug = pyqtSlot(str)(LogMixIn.logDebug)

【讨论】:

  • 感谢您的回复。很高兴知道可以在实例化具体的 QObject 子类之前修饰方法。但是,似乎我最初的问题可能有点含糊。 LogMixIn 位于一个单独的文件中,最好保持与 QT 无关。我的原始问题已更新以反映这一点。
  • 感谢您的更新,这正是我正在寻找的解决方案。
猜你喜欢
  • 2018-04-17
  • 2019-03-15
  • 2012-11-14
  • 2019-08-02
  • 2016-06-04
  • 2018-01-16
  • 2017-07-05
  • 2018-10-26
  • 2014-09-06
相关资源
最近更新 更多