首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >日志发出函数与QT发出信号之间的名称冲突

日志发出函数与QT发出信号之间的名称冲突
EN

Stack Overflow用户
提问于 2021-03-16 22:48:35
回答 1查看 577关注 0票数 1

每次调用日志处理程序发射函数时,我都试图发送一个Qt信号。但我认为MyLogHandler.emit和log.emit函数是相互冲突的。

代码语言:javascript
运行
复制
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')

错误:

代码语言:javascript
运行
复制
TypeError: emit() takes 2 positional arguments but 3 were given

更新:

我尝试使用复合(per @eyllanesc),但仍然无法将信号连接到QML文件。我不知道为什么我不能接收到QML的信号。它似乎并没有发射出任何东西。我做错了什么?

代码语言:javascript
运行
复制
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

代码语言:javascript
运行
复制
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
        }

    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-16 23:03:01

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

代码语言:javascript
运行
复制
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_()

更新:

代码语言:javascript
运行
复制
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()
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66664542

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档