Gui-Console fürs Logging

Stellt hier eure Projekte vor.
Internetseiten, Skripte, und alles andere bzgl. Python.
Antworten
Benutzeravatar
Blattlaus
User
Beiträge: 55
Registriert: Donnerstag 24. August 2006, 08:55

Freitag 20. Oktober 2006, 09:47

Da ich für mein aktuelles Problem die möglichkeit brauchte, alle Consolenangaben in ein Debugfenster zu schleusen, das bei bedarf angezeigt werden kann, habe ich mir mal eine Gui-Console gebastelt.
Das Ding erzeugt ein gefaktes stdout, so dass man am Anfang des Programms einfach ein sys.stdout = PseudoConsole.stdout machen kann und danach alle ausgaben von "print", usw automatisch in des Fenster geleitet werden. Zusätzlich wird jedes Zeile mit Timestamps versehen und man kann den ganzen kram als Datei speichern.

Sind knapp 120 Zeilen, steht unter der GPL und könnten für den ein oder anderen vielleicht ganz praktisch sein:

Code: Alles auswählen

# -*- coding: ISO-8859-1 -*-
###################################################################
#
# Copyright (C) 2006 Martin Thurau <martin.thurau(al)gmail.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of
# the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
###################################################################

__author__ = "Martin Thurau <martin.thurau(al)gmail.com>"
__version__ = "0.1"

import wx
from time import strftime


class PseudoFileOut:
    """A file like class which can be used as 'stdout'
    Eventhandlers cann be bind to get a an event if new Lines/Chars a written to the 'file'"""
    
    NEWTEXT = 1001
    
    def __init__(self):
        self.eventHandler = {}

    def readline(self):
        pass

    def write(self, s):
        try:
            self.eventHandler[PseudoFileOut.NEWTEXT](s)
        except KeyError:
            # no handler bind
            pass

    def writelines(self, lines):
        for line in lines:
            self.write(line)

    def flush(self):
        pass

    def isatty(self):
        return 1
    
    def bind(self, event, handler):
        """Binds a new eventHandler to the PseudoFileOut
        
            event:      the event. Possible are:
                            - PseudoFileOut.NEWTEXT
                            
            handler:    handler which is called for event"""
        
        self.eventHandler.update({event: handler})

class PseudoConsole(wx.Frame):
    """Provides a virtual "console" for GUI-programs which would like to show 
    a concole for debugging sometimes but don't like to use the normal System console.
    It's based on a wx.Frame, so you can Show() and Hide() it any time.
    Logging can be formatted via strftime options.
    
    To write to the console use the 'stdout' which is provided by this class"""
    
    def __init__(self, title="Console", size=(500,400), format="[%d./%m./%Y %H:%M:%S]: "):
        """init a new virtual Console window. It is hidden by default, so you have to call Show()
           
        Parameters:
            title   -   the title of the window
            size    -   size of window
            format  -   format string for strftime (default: "[%d./%m./%Y %H:%M:%S]: ")"""

        ## init Frame and controls
        wx.Frame.__init__(self, None, -1, "", style=wx.DEFAULT_FRAME_STYLE)
        self.sizer_staticbox = wx.StaticBox(self, -1, title)
        self.console = wx.TextCtrl(self, -1, "", style=wx.TE_MULTILINE|wx.TE_READONLY)
        self.saveToFile = wx.Button(self, -1, "Save to File")
        self.fileDialog = wx.FileDialog(self, "Save to File", wildcard = "*.txt", style = wx.SAVE | wx.OVERWRITE_PROMPT)
        
        ## layout them
        self.SetTitle(title)
        self.SetSize(size)
        self.SetBackgroundColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_INACTIVEBORDER))
        sizer = wx.StaticBoxSizer(self.sizer_staticbox, wx.VERTICAL)
        sizer.Add(self.console, 1, wx.EXPAND|wx.ADJUST_MINSIZE, 0)
        sizer.Add(self.saveToFile, 0, wx.ADJUST_MINSIZE, 0)
        self.SetAutoLayout(True)
        self.SetSizer(sizer)
        self.Layout()
        
        ## make an own pseudofile
        self.stdout = PseudoFileOut()
        
        ## set date format
        self.format = format
        
        ## eventhandler
        self.stdout.bind(PseudoFileOut.NEWTEXT, self.OnNewLine)
        self.saveToFile.Bind(wx.EVT_BUTTON, self.OnSaveButton)
          
    def OnNewLine(self, line):
        """Called when a new line received to the stdout attribute
        
        Parameters:
            line    -   the line which is added to console"""
        self.console.AppendText(strftime(self.format) + line + "\n")
        
    def OnSaveButton(self, event):
        """Called when the "Sace"-button is pressed.
        Shows file dialog and saves data to file"""
        
        if self.fileDialog.ShowModal() == wx.ID_OK:
            try:
                file = open(self.fileDialog.GetPath(),"w")
                file.writelines(self.console.GetValue())
            except:
                error = wx.MessageDialog(self,
                                    "Error", "File could not be saved",
                                    wx.OK | wx.ICON_ERROR
                                    )
                wx.MessageDialog.ShowModal(error)
            finally:
                file.close() 
Antworten