Seite 1 von 1

Fehler aus Klassen/Funktionen in zentralem QPlainTextEdit

Verfasst: Samstag 20. Juli 2013, 21:55
von lexaiden
Hallo,

aktuell landen alle meine Exceptions aus try/expect per print() in der console. Jetzt habe ich in meiner GUI (QT) ein QPlainTextEdit (plainTextEdit_log) angelegt, dort sollen sämtliche Fehlermeldungen die ich abfange bzw. selber generiere nicht mehr per print() auf die console wandern, sondern in plainTextEdit_log landen. Ich frag mich allerdings, wie ich das realisieren soll?!

Die Klasse MainWindow kann direkt auf das plainTextEdit_log zugreifen, aber wie schaffe ich das aus den anderen Klassen? Ich möchte eigentlich nicht jede Funktion so umbauen müssen das es den Fehler bis in die Klasse MainWindow zurück reicht (return), nur um es dort anzuzeigen. Das muss doch viel einfacher gehen?!

Hier mal ein (pseudocode) Minimalbeispiel, hab meine ganze Algorithmik entfernt (um es übersichtlich zu halten). Falls mich so keiner versteht, kann ich aber auch mal versuchen ein funktionierendes Minimalbeispiel zu produzieren.

Code: Alles auswählen

class MainWindow(QtGui.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.setupUi(self)
    def tuWas(self):
        try:
            raise Exception("Boooooomm...")
        expect Exception as inst:
            self.plainTextEdit_log.appendPlainText(inst)

class AndereKlasse():
    def __init__(self):
        pass
    def tuWas(self):
        try:
            raise Exception("Shit happens...")
        expect Exception as inst:
            self.plainTextEdit_log.appendPlainText(inst) # So gehts nicht, ich weiß auch wieso, aber wie kann ich es machen, das ich hier auf plainTextEdit_log zugreifen kann? 

class GanzAndereKlasse():
    def __init__(self):
        pass
    def tuWas(self):
        try:
            raise Exception("Toller Fehler")
        expect Exception as inst:
            self.plainTextEdit_log.appendPlainText(inst) # So gehts nicht, ich weiß auch wieso, aber wie kann ich es machen, das ich hier auf plainTextEdit_log zugreifen kann? 

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    sat = MainWindow()
    sat.show()
    sys.exit(app.exec_())

Re: Fehler aus Klassen/Funktionen in zentralem QPlainTextEdi

Verfasst: Samstag 20. Juli 2013, 22:32
von BlackJack
@lexaiden: Das `logging`-Modul verwenden und sich dafür einen Handler schreiben, der in das Widget schreibt, wäre eine Lösung.

Re: Fehler aus Klassen/Funktionen in zentralem QPlainTextEdi

Verfasst: Samstag 20. Juli 2013, 22:36
von lexaiden
Dann müsste ich doch aber trotzdem in jeder der Klassen eine Instanz des Logging Moduls erzeugen? Gibt es keinen Möglichekit, das ich eine globale Funktion wie "print()" erzeuge, die ich dann überall aufrufen kann und die dann direkt mein Feld beschreiben kann?

Re: Fehler aus Klassen/Funktionen in zentralem QPlainTextEdi

Verfasst: Samstag 20. Juli 2013, 22:51
von Sirius3
@lexaiden: von Modulen gibt es immer nur eine Instanz.

Re: Fehler aus Klassen/Funktionen in zentralem QPlainTextEdi

Verfasst: Samstag 20. Juli 2013, 23:00
von BlackJack
@lexaiden: Zusätzlich zu dem was Sirius3 schreibt: Ganz bestimmt nicht in jeder Klasse, sondern eher in jedem Modul, was bei Dir hoffentlich nicht auf das gleiche hinaus läuft. Und wenn man sich überall mit `getLogger()` den selben Logger geben lässt, kommt man am Ende auch mit einem einzigen Logger-Exemplar aus. Allerdings kann man auch mehrere Logger-Objekte erstellen, denn man kann, wenn man will, jeden separat konfigurieren. Das kann sinnvoll sein, wenn man nicht für jeden logischen Bereich der Anwendung den gleichen Grad an Details protokollieren möchte.

Re: Fehler aus Klassen/Funktionen in zentralem QPlainTextEdi

Verfasst: Mittwoch 24. Juli 2013, 22:33
von lexaiden
Nabend,

hab jetzt ein funktionsfähiges Minimalbeispiel produziert, hab ich es korrekt umgesetzt? :-)

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: utf-8 -*-

import sys
import logging
from logging import FileHandler, StreamHandler
from PyQt4 import QtGui, QtCore

class OwnLoggingHandler(logging.Handler):
    def __init__(self, textEdit, logger):
        logging.Handler.__init__(self)
        self.textEdit = textEdit
        logger.setLevel(logging.DEBUG)
        
        defaultFormatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s", "%d.%m.%Y %H:%M:%S")
        
        self.setFormatter(defaultFormatter)

        logConsole = StreamHandler()
        logConsole.setFormatter(defaultFormatter)
        logConsole.setLevel(logging.DEBUG)

        logFile = FileHandler("error.log", "a")
        logFile.setFormatter(defaultFormatter)
        logFile.setLevel(logging.DEBUG)

        logger.addHandler(self)
        logger.addHandler(logFile)
        logger.addHandler(logConsole)

    def emit(self, record):
        self.textEdit.append(self.format(record))


class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QMainWindow.__init__(self, parent)
        textEdit_log = QtGui.QTextEdit()
        textEdit_log.setReadOnly(True)
        logButton = QtGui.QAction('Generate Log Message', self)
        toolbar = self.addToolBar("LogButton")
        toolbar.addAction(logButton)
        self.setGeometry(100, 100, 600, 400)
        self.setCentralWidget(textEdit_log)
        self.statusBar().showMessage('Ready')

        self.connect(logButton, QtCore.SIGNAL('triggered()'), self.logButton_pressed)
        
        self.logger = logging.getLogger("GUI")
        OwnLoggingHandler(textEdit_log, self.logger)

        self.logger.debug("DEBUG")
        self.logger.warning("WARNING")
        self.logger.info("INFO")

        Test().calc()

    def __del__(self):
        self.logger.info("Gui closed")

    def logButton_pressed(self):
        self.logger.info("log Button pressed")


class Test:
    def __init__(self):
        self.logger = logging.getLogger("GUI")

    def __del__(self):
        self.logger.info("destroy class test")

    def calc(self):
        self.logger.info("calc")


if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    gui = MainWindow()
    gui.show()
    sys.exit(app.exec_())
Dank auch an lunar, das hier hat mir sehr geholfen: http://www.python-forum.de/viewtopic.ph ... 14#p179514