记录发射函数和Qt发射信号之间的名称冲突 [英] Conflicting names between logging emit function and QT emit signal
本文介绍了记录发射函数和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屋!
查看全文