Updated infoframe from Chris Fama
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@9729 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -22,7 +22,7 @@ import images
|
|||||||
|
|
||||||
|
|
||||||
_treeList = [
|
_treeList = [
|
||||||
('New since last release', ['ColourSelect', 'ImageBrowser',
|
('New since last release', ['ColourSelect', 'ImageBrowser', 'infoframe',
|
||||||
]),
|
]),
|
||||||
|
|
||||||
('Managed Windows', ['wxFrame', 'wxDialog', 'wxMiniFrame']),
|
('Managed Windows', ['wxFrame', 'wxDialog', 'wxMiniFrame']),
|
||||||
|
95
wxPython/demo/infoframe.py
Normal file
95
wxPython/demo/infoframe.py
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
|
||||||
|
from wxPython.wx import *
|
||||||
|
from wxPython.lib.infoframe import *
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
|
||||||
|
class MyFrame(wxFrame):
|
||||||
|
def __init__(self,output):
|
||||||
|
wxFrame.__init__(self,None,-1,"Close me...",size=(300,100))
|
||||||
|
menubar = wxMenuBar()
|
||||||
|
menu = wxMenu()
|
||||||
|
mID = NewId()
|
||||||
|
menu.Append(mID,"&Enable output","Display output frame")
|
||||||
|
EVT_MENU(self,mID,output.EnableOutput)
|
||||||
|
mID = NewId()
|
||||||
|
menu.Append(mID,"&Disable output","Close output frame")
|
||||||
|
EVT_MENU(self,mID,output.DisableOutput)
|
||||||
|
menubar.Append(menu,"&Output")
|
||||||
|
self.SetMenuBar(menubar)
|
||||||
|
output.SetParent(self)
|
||||||
|
output.SetOtherMenuBar(menubar,menuname="Output")
|
||||||
|
EVT_CLOSE(self,self.OnClose)
|
||||||
|
EVT_TIMER(self, -1, self.OnTimer)
|
||||||
|
|
||||||
|
self.timer = wxTimer(self, -1)
|
||||||
|
self.timer.Start(1000)
|
||||||
|
|
||||||
|
self.save_stdout = sys.stdout
|
||||||
|
sys.stdout = self.output = output
|
||||||
|
print "Hello!"
|
||||||
|
|
||||||
|
def OnClose(self,event):
|
||||||
|
sys.stdout = self.save_stdout
|
||||||
|
self.output.close()
|
||||||
|
self.timer.Stop()
|
||||||
|
self.timer = None
|
||||||
|
self.Destroy()
|
||||||
|
|
||||||
|
def OnTimer(self, evt):
|
||||||
|
print "This was printed with \"print\""
|
||||||
|
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
|
||||||
|
from wxPython.lib import infoframe
|
||||||
|
overview = infoframe.__doc__
|
||||||
|
|
||||||
|
def runTest(frame, nb, log):
|
||||||
|
"""
|
||||||
|
This method is used by the wxPython Demo Framework for integrating
|
||||||
|
this demo with the rest.
|
||||||
|
"""
|
||||||
|
win = MyFrame(wxPyInformationalMessagesFrame())
|
||||||
|
frame.otherWin = win
|
||||||
|
win.Show(1)
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
## class MyFrame(wxFrame):
|
||||||
|
## def __init__(self,output):
|
||||||
|
## wxFrame.__init__(self,None,-1,"Close me...",size=(300,100))
|
||||||
|
## EVT_CLOSE(self,self.OnClose)
|
||||||
|
## menubar = wxMenuBar()
|
||||||
|
## menu = wxMenu()
|
||||||
|
## mID = NewId()
|
||||||
|
## menu.Append(mID,"&Enable output","Display output frame")
|
||||||
|
## EVT_MENU(self,mID,output.EnableOutput)
|
||||||
|
## mID = NewId()
|
||||||
|
## menu.Append(mID,"&Disable output","Close output frame")
|
||||||
|
## EVT_MENU(self,mID,output.DisableOutput)
|
||||||
|
## menubar.Append(menu,"&Output")
|
||||||
|
## self.SetMenuBar(menubar)
|
||||||
|
## output.SetOtherMenuBar(menubar,menuname="Output")
|
||||||
|
|
||||||
|
## def OnClose(self,event):
|
||||||
|
## if isinstance(sys.stdout,wxPyInformationalMessagesFrame):
|
||||||
|
## sys.stdout.close()
|
||||||
|
## self.Destroy()
|
||||||
|
|
||||||
|
class MyApp(wxApp):
|
||||||
|
outputWindowClass = wxPyInformationalMessagesFrame
|
||||||
|
def OnInit(self):
|
||||||
|
frame = MyFrame(self.stdioWin)
|
||||||
|
frame.Show(TRUE)
|
||||||
|
self.SetTopWindow(frame)
|
||||||
|
if isinstance(sys.stdout,wxPyInformationalMessagesFrame):
|
||||||
|
sys.stdout.SetParent(frame)
|
||||||
|
#self.redirectStdio(None)# this is done automatically
|
||||||
|
# by the MyApp(1) call below
|
||||||
|
print "Starting.\n",
|
||||||
|
return true
|
||||||
|
|
||||||
|
app = MyApp(1)
|
||||||
|
app.MainLoop()
|
@@ -727,11 +727,12 @@ class wxPyOnDemandOutputWindow:
|
|||||||
def write(self, str):
|
def write(self, str):
|
||||||
if not wxThread_IsMain():
|
if not wxThread_IsMain():
|
||||||
# Aquire the GUI mutex before making GUI calls. Mutex is released
|
# Aquire the GUI mutex before making GUI calls. Mutex is released
|
||||||
# when locker is deleted a the end of this function.
|
# when locker is deleted at the end of this function.
|
||||||
locker = wxMutexGuiLocker()
|
locker = wxMutexGuiLocker()
|
||||||
|
|
||||||
if not self.frame:
|
if not self.frame:
|
||||||
self.frame = wxFrame(self.parent, -1, self.title)
|
self.frame = wxFrame(self.parent, -1, self.title,
|
||||||
|
style=wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE)
|
||||||
self.text = wxTextCtrl(self.frame, -1, "",
|
self.text = wxTextCtrl(self.frame, -1, "",
|
||||||
style = wxTE_MULTILINE|wxTE_READONLY)
|
style = wxTE_MULTILINE|wxTE_READONLY)
|
||||||
self.frame.SetSize(wxSize(450, 300))
|
self.frame.SetSize(wxSize(450, 300))
|
||||||
|
@@ -5,16 +5,32 @@ Released under wxWindows license etc.
|
|||||||
This is a fairly rudimentary, but slightly fancier tha
|
This is a fairly rudimentary, but slightly fancier tha
|
||||||
wxPyOnDemandOutputWindow (on which it's based; thanks Robin), version
|
wxPyOnDemandOutputWindow (on which it's based; thanks Robin), version
|
||||||
of the same sort of thing: a file-like class called
|
of the same sort of thing: a file-like class called
|
||||||
InformationalMessagesFrame.. This window also has a status bar with a
|
wxInformationalMessagesFrame. This window also has a status bar with a
|
||||||
couple of buttons for controlling the echoing of all output to a file
|
couple of buttons for controlling the echoing of all output to a file
|
||||||
with a randomly-chosen filename... [[A LITTLE MORE COULD BE SAID
|
with a randomly-chosen filename...
|
||||||
HERE]]
|
|
||||||
|
The class behaves similarly to wxPyOnDemandOutputWindow in that (at
|
||||||
|
least by default) the frame does not appear until written to, but is
|
||||||
|
somewhat different in that, either under programmatic (the
|
||||||
|
DisableOutput method) or user (the frame's close button, it's status
|
||||||
|
bar's "Dismiss" button, or a "Disable output" item of some menu,
|
||||||
|
perhaps of some other frame), the frame will be destroyed, an
|
||||||
|
associated file closed, and writing to it will then do nothing. This
|
||||||
|
can be reversed: either under programmatic (the EnableOutput method)
|
||||||
|
or user (an "Enable output" item of some menu), a new frame will be
|
||||||
|
opened,And an associated file (with a "randomly"selected filename)
|
||||||
|
opened for writing [to which all subsequent displayed messages will be
|
||||||
|
echoed].
|
||||||
|
|
||||||
|
Please note that, like wxPyOnDemandOutputWindow, the instance is not
|
||||||
|
itself a subclass of wxWindow: when the window is open (and ONLY
|
||||||
|
then), it's "frame" attribute is the actual instance of wFrame...
|
||||||
|
|
||||||
Typical usage:
|
Typical usage:
|
||||||
from wxPython.lib.infoframe import *
|
from wxPython.lib.infoframe import *
|
||||||
... # ... modify your wxApp as follows:
|
... # ... modify your wxApp as follows:
|
||||||
class myApp[wxApp):
|
class myApp[wxApp):
|
||||||
outputWindowClass = wxInformationalMessagesFrame
|
outputWindowClass = wxPyInformationalMessagesFrame
|
||||||
...
|
...
|
||||||
If you're running on Linux, you'll also have to supply an argument 1 to your
|
If you're running on Linux, you'll also have to supply an argument 1 to your
|
||||||
constructor of myApp to redirect stdout/stderr to this window (it's done
|
constructor of myApp to redirect stdout/stderr to this window (it's done
|
||||||
@@ -23,7 +39,7 @@ automatically for you on Windows).
|
|||||||
If you don't want to redirect stdout/stderr, but use the class directly: do
|
If you don't want to redirect stdout/stderr, but use the class directly: do
|
||||||
it this way:
|
it this way:
|
||||||
|
|
||||||
InformationalMessagesFrame = wxInformationalMessagesFrame\
|
InformationalMessagesFrame = wxPyInformationalMessagesFrame\
|
||||||
([options from progname (default ""),
|
([options from progname (default ""),
|
||||||
txt (default "informational
|
txt (default "informational
|
||||||
messages"])
|
messages"])
|
||||||
@@ -37,39 +53,52 @@ InformationalMessagesFrame([comma-separated list of items to
|
|||||||
|
|
||||||
The latter statement, of course, may be repeated arbitrarily often.
|
The latter statement, of course, may be repeated arbitrarily often.
|
||||||
The window will not appear until it is written to, and it may be
|
The window will not appear until it is written to, and it may be
|
||||||
manually closed by the user, after which it will not appear again
|
manually closed by the user, after which it will reappear again until
|
||||||
until written to... Also note that all output is echoed to a file with
|
written to... Also note that all output is echoed to a file with a
|
||||||
a randomly-generated name [see the mktemp module in the standard
|
randomly-generated name [see the mktemp module in the standard
|
||||||
library], in the directory given as the 'dir' keyword argument to the
|
library], in the directory given as the 'dir' keyword argument to the
|
||||||
InformationalMessagesFrame constructor [which has a default value of
|
InformationalMessagesFrame constructor [which has a default value of
|
||||||
'.'), or set via the method SetOutputDirectory...
|
'.'), or set via the method SetOutputDirectory... This file will be
|
||||||
|
closed with the window--a new one will be created [by default] upon
|
||||||
|
each subsequent reopening.
|
||||||
|
|
||||||
Please also note the methods EnableOutput and DisableOutput, and the
|
Please also note the methods EnableOutput and DisableOutput, and the
|
||||||
possible arguments for the constructor in the code below... (* TO DO:
|
possible arguments for the constructor in the code below... (* TO DO:
|
||||||
explain this here...*) The former, EnableOutput, displays the frame
|
explain this here...*) Neither of these methods need be used at all,
|
||||||
with an introductory message, opens a random file to which future
|
and in this case the frame will only be displayed once it has been
|
||||||
displayed output also goes, and sets the __debug__ variable of each
|
written to, like wxPyOnDemandOutputWindow.
|
||||||
module whose name begins with a capital letter {this happens to be the
|
|
||||||
author's personal practice; all my python module start with capital
|
The former, EnableOutput, displays the frame with an introductory
|
||||||
letters} to 1. This is so that you can say
|
message, opens a random file to which future displayed output also
|
||||||
|
goes (unless the nofile attribute is present), and sets the __debug__
|
||||||
|
variable of each module to 1 (unless the no __debug__ attribute is
|
||||||
|
present]. This is so that you can say, in any module whatsoever,
|
||||||
|
|
||||||
if __debug__:
|
if __debug__:
|
||||||
InformationalMessagesFrame("... with lots of %<Character> constructs"
|
InformationalMessagesFrame("... with lots of %<Character> constructs"
|
||||||
% TUPLE)
|
% TUPLE)
|
||||||
|
|
||||||
without worrying about a huge about of overhead in the case where
|
without worrying about the overhead of evaluating the arguments, and
|
||||||
debugging is not turned on. "Debug mode" can also be turned on by
|
calling the wxInformationalMessagesFrame instance, in the case where
|
||||||
selecting the item-"Enable debugging output" from the "Debug" menu of
|
debugging is not turned on. (This won't happen if the instance has an
|
||||||
a frame which has been either passed appropriately to the constructor
|
attribute no__debug__; you can arrange this by sub-classing...)
|
||||||
of the wxInformationalMessagesFrame (see the code), or set via the
|
|
||||||
SetOtherMenuBar method thereof. (I have found this to be an extremely
|
"Debug mode" can also be turned on by selecting the item-"Enable
|
||||||
useful tool, in lieu of a full wxPython debugger...) This menu item
|
output" from the "Debug" menu [the default--see the optional arguments
|
||||||
is also disabled, and an item "Disable debugging output" (which calls
|
to the SetOtherMenuBar method] of a frame which has been either passed
|
||||||
the method described in the next paragraph) is enabled. Note that
|
appropriately to the constructor of the wxInformationalMessagesFrame
|
||||||
these things need not be done: e.g., you don't need to have a "Debug"
|
(see the code), or set via the SetOtherMenuBar method thereof. This
|
||||||
menu with appropriate items; in this case simply do not call the
|
also writes an empty string to the instance, meaning that the frame
|
||||||
SetOtherMenuBar method or use the othermenubar keyword argument of the
|
will open (unless DisablOutput has been called) with an appropriate
|
||||||
class Instance constructor.
|
introductory message (which will vary according to whether the
|
||||||
|
instance/class has the "no __debug__" attribute)^ I have found this to
|
||||||
|
be an extremely useful tool, in lieu of a full wxPython debugger...
|
||||||
|
|
||||||
|
Following this, the menu item is also disabled, and an item "Disable
|
||||||
|
output" (again, by default) is enabled. Note that these need not be
|
||||||
|
done: e.g., you don't NEED to have a menu with appropriate items; in
|
||||||
|
this case simply do not call the SetOtherMenuBar method or use the
|
||||||
|
othermenubar keyword argument of the class instance constructor.
|
||||||
|
|
||||||
The DisableOutput method does the reverse of this; it closes the
|
The DisableOutput method does the reverse of this; it closes the
|
||||||
window (and associated file), and sets the __debug__ variable of each
|
window (and associated file), and sets the __debug__ variable of each
|
||||||
@@ -77,12 +106,17 @@ module whose name begins with a capital letter {this happens to be the
|
|||||||
author's personal practice; all my python module start with capital
|
author's personal practice; all my python module start with capital
|
||||||
letters} to 0. It also enables/disabled the appropriate menu items,
|
letters} to 0. It also enables/disabled the appropriate menu items,
|
||||||
if this was done previously (or SetOtherMenuBar has been called...).
|
if this was done previously (or SetOtherMenuBar has been called...).
|
||||||
|
Note too that after a call to DisableOutput, nothing further will be
|
||||||
|
done upon subsequent write()'s, until the EnableOutput method is
|
||||||
|
called, either explicitly or by the menu selection above...
|
||||||
|
|
||||||
Finally, note that the file-like method close() destroys the window
|
Finally, note that the file-like method close() destroys the window
|
||||||
(and any associated file) and there is a file-like method write()
|
(and closes any associated file) and there is a file-like method
|
||||||
which displays it's argument [actually, it's very similar to
|
write() which displays it's argument.
|
||||||
DisableOutput). Also, class instances are callable as noted above,
|
|
||||||
displaying successive arguments if this is done.
|
All (well, most) of this is made clear by the example code at the end
|
||||||
|
of this file, which is run if the file is run by itself; otherwise,
|
||||||
|
see the appropriate "stub" file in the wxPython demo.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -90,7 +124,7 @@ from wxPython.wx import *
|
|||||||
import string, sys, types, tempfile, os
|
import string, sys, types, tempfile, os
|
||||||
|
|
||||||
class _MyStatusBar(wxStatusBar):
|
class _MyStatusBar(wxStatusBar):
|
||||||
def __init__(self, parent,callbacks=None):
|
def __init__(self, parent,callbacks=None,useopenbutton=0):
|
||||||
wxStatusBar.__init__(self, parent, -1, style=wxTAB_TRAVERSAL)
|
wxStatusBar.__init__(self, parent, -1, style=wxTAB_TRAVERSAL)
|
||||||
self.SetFieldsCount(3)
|
self.SetFieldsCount(3)
|
||||||
|
|
||||||
@@ -99,14 +133,18 @@ class _MyStatusBar(wxStatusBar):
|
|||||||
ID = NewId()
|
ID = NewId()
|
||||||
self.button1 = wxButton(self,ID,"Dismiss",
|
self.button1 = wxButton(self,ID,"Dismiss",
|
||||||
style=wxTAB_TRAVERSAL)
|
style=wxTAB_TRAVERSAL)
|
||||||
EVT_BUTTON(self,ID,callbacks[0])
|
EVT_BUTTON(self,ID,self.OnButton1)
|
||||||
|
|
||||||
ID = NewId()
|
ID = NewId()
|
||||||
|
if not useopenbutton:
|
||||||
self.button2 = wxButton(self,ID,"Close File",
|
self.button2 = wxButton(self,ID,"Close File",
|
||||||
style=wxTAB_TRAVERSAL)
|
style=wxTAB_TRAVERSAL)
|
||||||
|
else:
|
||||||
|
self.button2 = wxButton(self,ID,"Open New File",
|
||||||
|
style=wxTAB_TRAVERSAL)
|
||||||
EVT_BUTTON(self,ID,self.OnButton2)
|
EVT_BUTTON(self,ID,self.OnButton2)
|
||||||
self.usealternate = 0
|
self.useopenbutton = useopenbutton
|
||||||
self.callbacks = [callbacks[1],callbacks[2]]
|
self.callbacks = callbacks
|
||||||
|
|
||||||
# figure out how tall to make the status bar
|
# figure out how tall to make the status bar
|
||||||
dc = wxClientDC(self)
|
dc = wxClientDC(self)
|
||||||
@@ -139,99 +177,171 @@ class _MyStatusBar(wxStatusBar):
|
|||||||
|
|
||||||
self.SetStatusWidths([-1,w1+15,w2+15])
|
self.SetStatusWidths([-1,w1+15,w2+15])
|
||||||
|
|
||||||
|
def OnButton1(self,event):
|
||||||
|
self.callbacks[0] ()
|
||||||
|
|
||||||
def OnButton2(self,event):
|
def OnButton2(self,event):
|
||||||
if self.usealternate:
|
if self.useopenbutton and self.callbacks[2] ():
|
||||||
if self.callbacks[1] ():
|
|
||||||
self.button2.SetLabel ("Close File")
|
self.button2.SetLabel ("Close File")
|
||||||
self.usealternate = 1 - self.usealternate
|
elif self.callbacks[1] ():
|
||||||
else:
|
|
||||||
if self.callbacks[0] ():
|
|
||||||
self.button2.SetLabel ("Open New File")
|
self.button2.SetLabel ("Open New File")
|
||||||
self.usealternate = 1 - self.usealternate
|
self.useopenbutton = 1 - self.useopenbutton
|
||||||
self.OnSize("")
|
self.OnSize("")
|
||||||
self.button2.Refresh(TRUE)
|
self.button2.Refresh(TRUE)
|
||||||
self.Refresh()
|
self.Refresh()
|
||||||
|
|
||||||
class wxInformationalMessagesFrame:#wxPyOnDemandOutputWindow):
|
|
||||||
parent = None
|
|
||||||
|
class wxPyInformationalMessagesFrame:
|
||||||
|
def __init__(self,
|
||||||
|
progname="",
|
||||||
|
text="informational messages",
|
||||||
|
dir='.',
|
||||||
|
menuname="Debug",
|
||||||
|
enableitem="Enable output",
|
||||||
|
disableitem="Disable output",
|
||||||
|
othermenubar=None):
|
||||||
|
|
||||||
|
self.SetOtherMenuBar(othermenubar,
|
||||||
|
menuname=menuname,
|
||||||
|
enableitem=enableitem,
|
||||||
|
disableitem=disableitem)
|
||||||
|
|
||||||
|
if hasattr(self,"othermenu") and self.othermenu is not None:
|
||||||
|
i = self.othermenu.FindMenuItem(self.menuname,self.disableitem)
|
||||||
|
self.othermenu.Enable(i,0)
|
||||||
|
i = self.othermenu.FindMenuItem(self.menuname,self.enableitem)
|
||||||
|
self.othermenu.Enable(i,1)
|
||||||
|
|
||||||
|
self.frame = None
|
||||||
|
self.title = "%s %s" % (progname,text)
|
||||||
|
self.parent = None # use the SetParent method if desired...
|
||||||
|
self.softspace = 1 # of rather limited use
|
||||||
|
if dir:
|
||||||
|
self.SetOutputDirectory(dir)
|
||||||
|
|
||||||
|
|
||||||
def SetParent(self, parent):
|
def SetParent(self, parent):
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
|
|
||||||
def SetOtherMenuBar(self,othermenu):
|
|
||||||
self.othermenu = othermenu
|
|
||||||
|
|
||||||
def __init__(self,progname="",text="informational messages",dir=',',
|
def SetOtherMenuBar(self,
|
||||||
othermenubar=None):
|
othermenu,
|
||||||
self.othermenu = othermenubar
|
menuname="Debug",
|
||||||
self.frame = None
|
enableitem="Enable output",
|
||||||
self.title = "%s %s" % (progname,text)
|
disableitem="Disable output"):
|
||||||
self.softspace = 1 # of rather limited use
|
self.othermenu = othermenu
|
||||||
if dir:
|
self.menuname = menuname
|
||||||
self.SetOutputDirectory(dir)
|
self.enableitem = enableitem
|
||||||
if __debug__:
|
self.disableitem = disableitem
|
||||||
self.EnableOutput()
|
|
||||||
#wxPyOnDemandOutputWindow.__init__(self,self.title)
|
|
||||||
for m in sys.modules.values():
|
|
||||||
if m is not None:# and m.__dict__.has_key("__debug__"):
|
|
||||||
m.__dict__["__debug__"] = self.Enabled
|
|
||||||
|
|
||||||
f = None
|
f = None
|
||||||
|
|
||||||
|
|
||||||
def write(self,string):
|
def write(self,string):
|
||||||
|
if not wxThread_IsMain():
|
||||||
|
# Aquire the GUI mutex before making GUI calls. Mutex is released
|
||||||
|
# when locker is deleted at the end of this function.
|
||||||
|
locker = wxMutexGuiLocker()
|
||||||
|
|
||||||
if self.Enabled:
|
if self.Enabled:
|
||||||
if self.f:
|
if self.f:
|
||||||
self.f.write(string)
|
self.f.write(string)
|
||||||
self.f.flush()
|
self.f.flush()
|
||||||
|
|
||||||
move = 1
|
move = 1
|
||||||
if hasattr(self,"text")\
|
if (hasattr(self,"text")
|
||||||
and self.text is not None\
|
and self.text is not None
|
||||||
and self.text.GetInsertionPoint()\
|
and self.text.GetInsertionPoint() != self.text.GetLastPosition()):
|
||||||
<> self.text.GetLastPosition():
|
|
||||||
move = 0
|
move = 0
|
||||||
|
|
||||||
if not self.frame:
|
if not self.frame:
|
||||||
self.frame = wxFrame(self.parent, -1, self.title)
|
self.frame = wxFrame(self.parent, -1, self.title, size=(450, 300),
|
||||||
|
style=wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE)
|
||||||
self.text = wxTextCtrl(self.frame, -1, "",
|
self.text = wxTextCtrl(self.frame, -1, "",
|
||||||
style = wxTE_MULTILINE|wxTE_READONLY
|
style = wxTE_MULTILINE|wxTE_READONLY|wxTE_RICH)
|
||||||
|wxTE_RICH)# appears to cause problem?
|
|
||||||
self.frame.sb = _MyStatusBar(self.frame,
|
self.frame.sb = _MyStatusBar(self.frame,
|
||||||
callbacks=[self.DisableOutput,
|
callbacks=[self.DisableOutput,
|
||||||
self.CloseFile,
|
self.CloseFile,
|
||||||
self.OpenNewFile])
|
self.OpenNewFile],
|
||||||
|
useopenbutton=hasattr(self,
|
||||||
|
"nofile"))
|
||||||
self.frame.SetStatusBar(self.frame.sb)
|
self.frame.SetStatusBar(self.frame.sb)
|
||||||
self.frame.SetSize(wxSize(450, 300))
|
|
||||||
self.frame.Show(true)
|
self.frame.Show(true)
|
||||||
EVT_CLOSE(self.frame, self.OnCloseWindow)
|
EVT_CLOSE(self.frame, self.OnCloseWindow)
|
||||||
|
|
||||||
|
if hasattr(self,"nofile"):
|
||||||
|
self.text.AppendText(
|
||||||
|
"Please close this window (or select the "
|
||||||
|
"'Dismiss' button below) when desired. By "
|
||||||
|
"default all messages written to this window "
|
||||||
|
"will NOT be written to a file--you "
|
||||||
|
"may change this by selecting 'Open New File' "
|
||||||
|
"below, allowing you to select a "
|
||||||
|
"new file...\n\n")
|
||||||
|
else:
|
||||||
|
tempfile.tempdir = self.dir
|
||||||
|
filename = os.path.abspath(tempfile.mktemp ())
|
||||||
|
self.text.AppendText(
|
||||||
|
"Please close this window (or select the "
|
||||||
|
"'Dismiss' button below) when desired. By "
|
||||||
|
"default all messages written to this window "
|
||||||
|
"will also be written to the file '%s'--you "
|
||||||
|
"may close this file by selecting 'Close "
|
||||||
|
"File' below, whereupon this button will be "
|
||||||
|
"replaced with one allowing you to select a "
|
||||||
|
"new file...\n\n" % filename)
|
||||||
|
try:
|
||||||
|
self.f = open(filename, 'w')
|
||||||
|
self.frame.sb.SetStatusText("File '%s' opened..."
|
||||||
|
% filename,
|
||||||
|
0)
|
||||||
|
except EnvironmentError:
|
||||||
|
self.frame.sb.SetStatusText("File creation failed "
|
||||||
|
"(filename '%s')..."
|
||||||
|
% filename,
|
||||||
|
0)
|
||||||
self.text.AppendText(string)
|
self.text.AppendText(string)
|
||||||
## if __debug__ and type(sys.__stderr__) == types.FileType\
|
|
||||||
## and sys.__stderr__.isatty():
|
|
||||||
## sys.__stderr__.write(
|
|
||||||
## "%s.write(): self.text.GetInsertionPoint() = %s, "\
|
|
||||||
## "self.text.GetLastPosition() = %s, "\
|
|
||||||
## "move = %d\n" % (self,
|
|
||||||
## self.text.GetInsertionPoint(),
|
|
||||||
## self.text.GetLastPosition(),
|
|
||||||
## move))
|
|
||||||
if move:
|
if move:
|
||||||
self.text.ShowPosition(self.text.GetLastPosition())
|
self.text.ShowPosition(self.text.GetLastPosition())
|
||||||
|
|
||||||
Enabled = __debug__
|
if not hasattr(self,"no__debug__"):
|
||||||
|
for m in sys.modules.values():
|
||||||
|
if m is not None:# and m.__dict__.has_key("__debug__"):
|
||||||
|
m.__dict__["__debug__"] = 1
|
||||||
|
|
||||||
|
if hasattr(self,"othermenu") and self.othermenu is not None:
|
||||||
|
i = self.othermenu.FindMenuItem(self.menuname,self.disableitem)
|
||||||
|
self.othermenu.Enable(i,1)
|
||||||
|
i = self.othermenu.FindMenuItem(self.menuname,self.enableitem)
|
||||||
|
self.othermenu.Enable(i,0)
|
||||||
|
|
||||||
|
|
||||||
|
Enabled = 1
|
||||||
|
|
||||||
def OnCloseWindow(self, event, exiting=0):
|
def OnCloseWindow(self, event, exiting=0):
|
||||||
if self.f:
|
if self.f:
|
||||||
self.f.close()
|
self.f.close()
|
||||||
self.f = None
|
self.f = None
|
||||||
if hasattr(self,"othermenu") and self.othermenu is not None\
|
|
||||||
and self.frame is not None\
|
if (hasattr(self,"othermenu") and self.othermenu is not None
|
||||||
and not exiting:
|
and self.frame is not None
|
||||||
i = self.othermenu.FindMenuItem('Debug','Disable debugging output')
|
and not exiting):
|
||||||
|
|
||||||
|
i = self.othermenu.FindMenuItem(self.menuname,self.disableitem)
|
||||||
self.othermenu.Enable(i,0)
|
self.othermenu.Enable(i,0)
|
||||||
i = self.othermenu.FindMenuItem('Debug','Enable debugging output')
|
i = self.othermenu.FindMenuItem(self.menuname,self.enableitem)
|
||||||
self.othermenu.Enable(i,1)
|
self.othermenu.Enable(i,1)
|
||||||
|
|
||||||
|
if not hasattr(self,"no__debug__"):
|
||||||
for m in sys.modules.values():
|
for m in sys.modules.values():
|
||||||
if m is not None:# and m.__dict__.has_key("__debug__"):
|
if m is not None:# and m.__dict__.has_key("__debug__"):
|
||||||
m.__dict__["__debug__"] = 0
|
m.__dict__["__debug__"] = 0
|
||||||
if self.frame is not None: # should be true, but, e.g., allows
|
|
||||||
|
if self.frame is not None: # typically true, but, e.g., allows
|
||||||
# DisableOutput method (which calls this
|
# DisableOutput method (which calls this
|
||||||
# one) to be called when the frame is not
|
# one) to be called when the frame is not
|
||||||
# actually open, so that it is always safe
|
# actually open, so that it is always safe
|
||||||
@@ -239,40 +349,27 @@ class wxInformationalMessagesFrame:#wxPyOnDemandOutputWindow):
|
|||||||
frame = self.frame
|
frame = self.frame
|
||||||
self.frame = self.text = None
|
self.frame = self.text = None
|
||||||
frame.Destroy()
|
frame.Destroy()
|
||||||
self.Enabled = 0
|
|
||||||
|
|
||||||
def EnableOutput(self,othermenubar=None):
|
|
||||||
if othermenubar is not None:
|
|
||||||
self.othermenu = othermenubar
|
|
||||||
self.Enabled = 1
|
self.Enabled = 1
|
||||||
for m in sys.modules.values():
|
|
||||||
if m is not None:# and m.__dict__.has_key("__debug__"):
|
|
||||||
m.__dict__["__debug__"] = 1
|
def EnableOutput(self,
|
||||||
if hasattr(self,"othermenu") and self.othermenu is not None:
|
event=None,# event must be the first optional argument...
|
||||||
i = self.othermenu.FindMenuItem('Debug','Disable debugging output')
|
othermenubar=None,
|
||||||
self.othermenu.Enable(i,1)
|
menuname="Debug",
|
||||||
i = self.othermenu.FindMenuItem('Debug','Enable debugging output')
|
enableitem="Enable output",
|
||||||
self.othermenu.Enable(i,0)
|
disableitem="Disable output"):
|
||||||
if not self.f:
|
|
||||||
try:
|
if othermenubar is not None:
|
||||||
filename = tempfile.mktemp ()
|
self.SetOtherMenuBar(othermenubar,
|
||||||
self.write("Please close this window (or select the "
|
menuname=menuname,
|
||||||
"'Dismiss' button below) when desired. By "
|
enableitem=enableitem,
|
||||||
"default all messages written to this window "
|
disableitem=disableitem)
|
||||||
"will also be written to the file '%s'--you "
|
self.Enabled = 1
|
||||||
"may close this file by selecting 'Close "
|
if self.f:
|
||||||
"File' below, whereupon this button will be "
|
self.f.close()
|
||||||
"replaced with one allowing you to select a "
|
self.f = None
|
||||||
"new file...\n\n" % os.path.abspath(filename))
|
self.write("")
|
||||||
self.f = open (filename,'w')
|
|
||||||
self.frame.sb.SetStatusText("File '%s' opened..."
|
|
||||||
% os.path.abspath(self.f.name),
|
|
||||||
0)
|
|
||||||
except EnvironmentError:
|
|
||||||
self.frame.sb.SetStatusText("File creation failed (filename "
|
|
||||||
"'%s')..."
|
|
||||||
% os.path.abspath(filename),
|
|
||||||
0)
|
|
||||||
|
|
||||||
def CloseFile(self):
|
def CloseFile(self):
|
||||||
if self.f:
|
if self.f:
|
||||||
@@ -289,6 +386,7 @@ class wxInformationalMessagesFrame:#wxPyOnDemandOutputWindow):
|
|||||||
self.frame.sb.Refresh()
|
self.frame.sb.Refresh()
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
||||||
def OpenNewFile(self):
|
def OpenNewFile(self):
|
||||||
self.CloseFile()
|
self.CloseFile()
|
||||||
dlg = wxFileDialog(self.frame,
|
dlg = wxFileDialog(self.frame,
|
||||||
@@ -308,37 +406,50 @@ class wxInformationalMessagesFrame:#wxPyOnDemandOutputWindow):
|
|||||||
self.frame.sb.SetStatusText("File '%s' opened..."
|
self.frame.sb.SetStatusText("File '%s' opened..."
|
||||||
% os.path.abspath(self.f.name),
|
% os.path.abspath(self.f.name),
|
||||||
0)
|
0)
|
||||||
|
if hasattr(self,"nofile"):
|
||||||
|
self.frame.sb = _MyStatusBar(self.frame,
|
||||||
|
callbacks=[self.DisableOutput,
|
||||||
|
self.CloseFile,
|
||||||
|
self.OpenNewFile])
|
||||||
|
self.frame.SetStatusBar(self.frame.sb)
|
||||||
|
if hasattr(self,"nofile"):
|
||||||
|
delattr(self,"nofile")
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
def DisableOutput(self,exiting=0):
|
|
||||||
|
def DisableOutput(self,
|
||||||
|
event=None,# event must be the first optional argument...
|
||||||
|
exiting=0):
|
||||||
self.write("<InformationalMessagesFrame>.DisableOutput()\n")
|
self.write("<InformationalMessagesFrame>.DisableOutput()\n")
|
||||||
self.CloseFile()
|
|
||||||
self.Enabled = 0
|
|
||||||
if hasattr(self,"othermenu") and self.othermenu is not None:
|
|
||||||
i = self.othermenu.FindMenuItem('Debug','Disable debugging output')
|
|
||||||
self.othermenu.Enable(i,0)
|
|
||||||
i = self.othermenu.FindMenuItem('Debug','Enable debugging output')
|
|
||||||
self.othermenu.Enable(i,1)
|
|
||||||
if hasattr(self,"frame") \
|
if hasattr(self,"frame") \
|
||||||
and self.frame is not None:
|
and self.frame is not None:
|
||||||
self.OnCloseWindow("Dummy",exiting=exiting)
|
self.OnCloseWindow("Dummy",exiting=exiting)
|
||||||
|
self.Enabled = 0
|
||||||
|
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
self.DisableOutput()
|
self.DisableOutput()
|
||||||
|
|
||||||
|
|
||||||
def flush(self):
|
def flush(self):
|
||||||
if self.text:
|
if self.text:
|
||||||
self.text.SetInsertionPointEnd()
|
self.text.SetInsertionPointEnd()
|
||||||
wxYield()
|
wxYield()
|
||||||
|
|
||||||
|
|
||||||
def __call__(self,* args):
|
def __call__(self,* args):
|
||||||
for s in args:
|
for s in args:
|
||||||
self.write (str (s))
|
self.write (str (s))
|
||||||
|
|
||||||
def SetOutputDirectory(self,dir):
|
|
||||||
self.dir = tempfile.tempdir = dir
|
|
||||||
|
|
||||||
class DummyFile:
|
def SetOutputDirectory(self,dir):
|
||||||
|
self.dir = os.path.abspath(dir)
|
||||||
|
## sys.__stderr__.write("Directory: os.path.abspath(%s) = %s\n"
|
||||||
|
## % (dir,self.dir))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class Dummy_wxPyInformationalMessagesFrame:
|
||||||
def __init__(self,progname=""):
|
def __init__(self,progname=""):
|
||||||
self.softspace = 1
|
self.softspace = 1
|
||||||
def __call__(self,*args):
|
def __call__(self,*args):
|
||||||
@@ -358,40 +469,3 @@ class DummyFile:
|
|||||||
def SetParent(self,wX):
|
def SetParent(self,wX):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
__debug__ = 1
|
|
||||||
|
|
||||||
ImportErrors = 0
|
|
||||||
try:
|
|
||||||
import Errors
|
|
||||||
importErrors = 1
|
|
||||||
except ImportError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
class MyFrame(wxFrame):
|
|
||||||
def __init__(self):
|
|
||||||
wxFrame.__init__(self,None,-1,"Close me...",size=(300,10))
|
|
||||||
EVT_CLOSE(self,self.OnClose)
|
|
||||||
|
|
||||||
def OnClose(self,event):
|
|
||||||
if isinstance(sys.stdout,wxInformationalMessagesFrame):
|
|
||||||
sys.stdout.close()# shouldn't be necessary?
|
|
||||||
self.Destroy()
|
|
||||||
|
|
||||||
class MyApp(wxApp):
|
|
||||||
outputWindowClass = wxInformationalMessagesFrame
|
|
||||||
def OnInit(self):
|
|
||||||
if ImportErrors:
|
|
||||||
sys.stderr = Errors.NonWindowingErrorWindow(
|
|
||||||
file=self.stdioWin)
|
|
||||||
print "Starting.\n",
|
|
||||||
frame = MyFrame()
|
|
||||||
frame.Show(TRUE)
|
|
||||||
self.SetTopWindow(frame)
|
|
||||||
if isinstance(sys.stdout,wxInformationalMessagesFrame):
|
|
||||||
sys.stdout.SetParent(frame)# Shouldn't this mean the
|
|
||||||
#wxInternationalMessagesFrame is Destroy()'d when MFrame is?
|
|
||||||
return true
|
|
||||||
|
|
||||||
app = MyApp()
|
|
||||||
app.MainLoop()
|
|
||||||
|
Reference in New Issue
Block a user