我还没有在其他标题相似的主题中找到答案。假设我有一个如下所示的 logging.conf:
[loggers]
keys=root,analyzer
[handlers]
keys=consoleHandler,analyzerFileHandler
[formatters]
keys=consoleFormatter,logFormatter
[logger_root]
level=DEBUG
handlers=consoleHandler,analyzerFileHandler
[logger_analyzer]
level=DEBUG
handlers=consoleHandler,analyzerFileHandler
qualname=analyzer
propagate=0
[handler_consoleHandler]
class=StreamHandler
level=INFO
formatter=consoleFormatter
args=(sys.stdout,)
[handler_analyzerFileHandler]
class=FileHandler
level=DEBUG
formatter=logFormatter
args=('analyzer.log','w')
[formatter_consoleFormatter]
format=%(asctime)s - %(name)s - %(levelname)s | %(message)s
datefmt=%m/%d/%Y %X
[formatter_logFormatter]
format=%(asctime)s - %(levelname)s | %(message)s
datefmt=%m/%d/%Y %X
A logger = logging.getLogger('analyzer')会将文本发送到日志文件和控制台,我怎样才能使 sys.stdout 转到 QPlainTextEdit() 小部件而不是控制台?
编辑
好的,看看这篇文章,我做了这段代码。该帖子的代码很好,但由于某种原因它没有解决问题,您可以注释掉记录器的所有实例,但最终仍会将打印事件发送到 Qwidget。记录器与程序的其余部分没有真正的交互,它就在那里。我想我可以通过编写一个类来解决这个问题,该类将我想要的任何内容作为文本并将其分别发送到打印和记录器:
import logging
from logging.config import fileConfig
from os import getcwd
import sys
from PyQt4.QtCore import QObject,\
pyqtSignal
from PyQt4.QtGui import QDialog, \
QVBoxLayout, \
QPushButton, \
QTextBrowser,\
QApplication
class XStream(QObject):
_stdout = None
_stderr = None
messageWritten = pyqtSignal(str)
def flush( self ):
pass
def fileno( self ):
return -1
def write( self, msg ):
if ( not self.signalsBlocked() ):
self.messageWritten.emit(unicode(msg))
@staticmethod
def stdout():
if ( not XStream._stdout ):
XStream._stdout = XStream()
sys.stdout = XStream._stdout
return XStream._stdout
@staticmethod
def stderr():
if ( not XStream._stderr ):
XStream._stderr = XStream()
sys.stderr = XStream._stderr
return XStream._stderr
class XLogger():
def __init__(self, name):
self.logger = logging.getLogger(name)
def debug(self,text):
print text
self.logger.debug(text)
def info(self,text):
print text
self.logger.info(text)
def warning(self,text):
print text
self.logger.warning(text)
def error(self,text):
print text
self.logger.error(text)
class MyDialog(QDialog):
def __init__( self, parent = None ):
super(MyDialog, self).__init__(parent)
# setup the ui
self._console = QTextBrowser(self)
self._button = QPushButton(self)
self._button.setText('Test Me')
# create the layout
layout = QVBoxLayout()
layout.addWidget(self._console)
layout.addWidget(self._button)
self.setLayout(layout)
# create connections
XStream.stdout().messageWritten.connect( self._console.insertPlainText )
XStream.stderr().messageWritten.connect( self._console.insertPlainText )
self.xlogger = XLogger('analyzer')
self._button.clicked.connect(self.test)
def test( self ):
# log some stuff
self.xlogger.debug("Testing debug")
self.xlogger.info('Testing info')
self.xlogger.warning('Testing warning')
self.xlogger.error('Testing error')
if ( __name__ == '__main__' ):
fileConfig(''.join([getcwd(),'/logging.conf']))
app = None
if ( not QApplication.instance() ):
app = QApplication([])
dlg = MyDialog()
dlg.show()
“交叉记录器”将所有内容发送到日志和 Qwidget,但它也将除调试之外的所有内容发送到 aptana 控制台:
02/05/2013 17:38:42 - analyzer - INFO | Testing info
02/05/2013 17:38:42 - analyzer - WARNING | Testing warning
02/05/2013 17:38:42 - analyzer - ERROR | Testing error
虽然analyzer.log 有:
02/05/2013 17:38:42 - DEBUG | Testing debug
02/05/2013 17:38:42 - INFO | Testing info
02/05/2013 17:38:42 - WARNING | Testing warning
02/05/2013 17:38:42 - ERROR | Testing error
奇怪的是,调试是唯一没有进入 Aptana 控制台的,从我的 logging.conf 中 [logger_analyzer] 下的处理程序中删除consoleHandler解决了它写入 Aptana 控制台的问题,可能与[handler_consoleHandler] 下的args=(sys.stdout,) 。我想它可以解决我的问题,而无需在 Qtext 对象的处理程序中编写代码,从而否定 logging.conf 文件。如果有人有更优雅的解决方案来使用 logging.conf 文件,该文件以某种方式设法将其控制台输出重定向到您选择的 Qwidget,请随时发布。谢谢。