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()