2016-12-16 3 views
0

dieses kleine Schnipsel Gegeben:Python Log-Ausgabe sowohl GUI und Konsole

import sys 
import os 
import logging 
from PyQt5 import QtGui, QtWidgets, QtCore 

log = logging.getLogger("Foo") 
logging.basicConfig(
    level=logging.INFO, format='%(levelname)s: %(filename)s - %(message)s') 
log.setLevel(logging.DEBUG) 


class ConsolePanelHandler(logging.Handler): 

    def __init__(self, parent): 
     logging.Handler.__init__(self) 
     self.parent = parent 

    def emit(self, record): 
     self.parent.write(self.format(record)) 


class Foo(QtWidgets.QWidget): 

    def __init__(self, parent=None): 
     QtWidgets.QWidget.__init__(self, parent) 

     self.textEdit = QtWidgets.QTextEdit(self) 
     self.textEdit.setLineWrapMode(QtWidgets.QTextEdit.NoWrap) 
     self.textEdit.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse) 

     vbox = QtWidgets.QVBoxLayout() 
     self.setLayout(vbox) 
     vbox.addWidget(self.textEdit) 

    def write(self, s): 
     self.textEdit.setFontWeight(QtGui.QFont.Normal) 
     self.textEdit.append(s) 


if __name__ == "__main__": 
    app = QtWidgets.QApplication(sys.argv) 
    console_panel = Foo() 
    handler = ConsolePanelHandler(console_panel) 
    log.addHandler(handler) 

    log.info("Getting logger {0} - {1}".format(id(log), log.handlers)) 
    [log.debug("This is normal text " + str(i)) for i in range(5)] 
    console_panel.show() 

    sys.exit(app.exec_()) 

Fragen:

  • Warum log zu schreiben sowohl die Konsole und gui? So weit ich weiß log.handlers len sollte nur 1 sein.
  • Wie kann ich nur auf die GUI schreiben unterdrücken die Konsole Nachrichten?
  • Warum ist das GUI-Format nicht das von BasicConfig angegebene?

Antwort

1

Ihr Problem wird durch den Aufruf basicConfig() beim Import verursacht - wie documented, dies fügt eine Konsole Logger zum Root-Logger, wenn sie keine Handler bereits haben.

Sie müssen diesen Aufruf entfernen und eine Zeile in der if __name__ == '__main__' Klausel hinzuzufügen:

handler.setFormatter(logging.Formatter('%(levelname)s: %(filename)s - %(message)s')) 

und Sie sollten dann das Ergebnis bekommen Sie erwartet hatten.

Der Grund, warum Sie beide Meldungen gesehen haben, ist der, wie Informationen zwischen Loggern und Handlern fließen, die in der Dokumentation here beschrieben sind.

+0

Eine Frage jedoch, wenn Sie sagen 'das fügt dem Stammlogger einen Konsolenlogger hinzu, wenn er noch keine Handler hat' ... warum zeigt' log.handlers' nicht den Konsolenlogger nach dem Aufruf von ' basicConfig() '? – BPL

+0

@BPL 'log' ist nicht der Root-Logger und' log.handlers' hat den einen Logger, den Sie hinzugefügt haben, korrekt. Der Aufruf 'basicConfig()' fügt dem Stammlogger Handler hinzu, die auch für die Ausgabe von Ereignissen verwendet werden, die in 'log' protokolliert sind, wie im Link" Informationsfluss "in meiner Antwort angegeben. –

+0

Gibt es eine Möglichkeit, die Instanz oder ID() dieser Root-Logger zu bekommen? Ich bin nur neugierig zu sehen, wo BasicConfig() den Handler hinzugefügt hat. – BPL