记录发射函数和Qt发射信号之间的名称冲突 [英] Conflicting names between logging emit function and QT emit signal

查看:0
本文介绍了记录发射函数和Qt发射信号之间的名称冲突的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试在每次调用日志记录处理程序emit函数时发送一个Qt信号。但我认为MyLogHandler.emit和log.emit函数冲突。

from PySide2.QtCore import QObject, Signal
import logging

class MyLogHandler(logging.Handler, QObject):
    log = Signal(str)

    def emit(self, record):
        self.log.emit('send')

if __name__ == "__main__":
    logging.getLogger().addHandler(MyLogHandler())
    logging.warning('logging test')

错误:

TypeError: emit() takes 2 positional arguments but 3 were given

更新:

我已经尝试使用组合(per@eyllanesc),但我仍然无法将信号连接到QML文件。我不知道为什么我接收不到QML格式的信号。它看起来并没有散发出任何东西。我做错了什么?

from functools import cached_property
import logging
import sys

from PySide2.QtGui import QGuiApplication
from PySide2.QtQml import QQmlApplicationEngine
from PySide2.QtCore import QCoreApplication, QObject, QTimer, Signal, QUrl

class Main(QObject):
    log = Signal(str)


class Log(object):
    def __init__(self):
        logging.basicConfig(
            level=logging.DEBUG,
            format="%(asctime)s [%(levelname)s] %(message)s",
            handlers=[
                logging.FileHandler("debug.log", mode='w'),
                logging.StreamHandler(),
                MyLogHandler()
            ]
        )

class MyLogHandler(logging.Handler):
    @cached_property
    def main(self):
        return Main()

    def emit(self, record):
        msg = self.format(record)
        self.main.log.emit(msg)


if __name__ == "__main__":
    app = QGuiApplication(sys.argv)
    engine = QQmlApplicationEngine()

    main = Main()

    Log()

    QTimer.singleShot(1000, lambda: logging.warning("logging test"))
    engine.rootContext().setContextProperty("main", main)
    engine.load(QUrl("Main3.qml"))
    app.exec_()

QML:Main3.qml

import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.15

Window {
    width: 500
    height: 500
    visible: true
    title: qsTr("MIST")

    Text {
        id: text
        anchors.fill: parent

    }

    Connections {
        target: main

        function onLog(msg) {
            text.text = msg
        }

    }
}

推荐答案

问题是两个基类都有一个emit()方法导致冲突。解决办法不是使用继承,而是使用组合:

from functools import cached_property
import logging

from PySide2.QtCore import QCoreApplication, QObject, QTimer, Signal


class Bridge(QObject):
    log = Signal(str)


class MyLogHandler(logging.Handler):
    @cached_property
    def bridge(self):
        return Bridge()

    def emit(self, record):
        msg = self.format(record)
        self.bridge.log.emit(msg)


if __name__ == "__main__":
    app = QCoreApplication()

    handler = MyLogHandler()
    handler.bridge.log.connect(print)

    logging.getLogger().addHandler(handler)

    QTimer.singleShot(1000, lambda: logging.warning("logging test"))
    QTimer.singleShot(2000, QCoreApplication.quit)

    app.exec_()

更新:

import logging
import sys

from PySide2.QtCore import QObject, QTimer, QUrl, Signal
from PySide2.QtGui import QGuiApplication
from PySide2.QtQml import QQmlApplicationEngine


class Main(QObject):
    log = Signal(str)


class QLogHandler(logging.Handler):
    def __init__(self, emitter):
        super().__init__()
        self._emitter = emitter

    @property
    def emitter(self):
        return self._emitter

    def emit(self, record):
        msg = self.format(record)
        self.emitter.log.emit(msg)


def configure_logging(*, handlers):
    logging.basicConfig(
        level=logging.DEBUG,
        format="%(asctime)s [%(levelname)s] %(message)s",
        handlers=handlers,
    )


def main():
    app = QGuiApplication()

    main = Main()

    configure_logging(
        handlers=[
            logging.FileHandler("debug.log", mode="w"),
            logging.StreamHandler(),
            QLogHandler(main),
        ]
    )

    engine = QQmlApplicationEngine()
    engine.rootContext().setContextProperty("main", main)
    engine.load(QUrl("Main3.qml"))

    QTimer.singleShot(1000, lambda: logging.warning("logging test"))

    ret = app.exec_()
    sys.exit(ret)


if __name__ == "__main__":
    main()

这篇关于记录发射函数和Qt发射信号之间的名称冲突的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆