I have an app with two independent Frames, A and B. B can’t be a child of A because when A is minimized B must be Show()'n. So, when A Hide()'s itself it needs the Show() B and vice-versa.
Normally, the top level window can do the hiding and showing, but in this case there isn’t one. It seems to me that the easiest solution would be to add attributes to the wx.App :
if name == ‘main’ :
app = wx.App()
frmA = GuiFrame( none )
frmB = WorkFrame( none )
app.frmA = frmA
app.frmB = frmB
frmA.Show()
app.MainLoop()
···
Within Frame A:
…
app = wx.GetApp()
app.frmB.Show()
self.Hide() # or “app.A.Hide()” since app.frmA == self
This seems to solve the problem in a clean way. I can’t think of any hazards doing this since app is an object like any other python object.
Does anyone have more thoughts about this scheme ?
Ray Pasco
I’m not seeing anything wrong with this off the top of my head. Robin may have a different take. I have used pubsub for this sort of thing myself though.
Ray Pasco wrote:
I have an app with two independent Frames, A and B. B can't be a child
of A because when A is minimized B must be Show()'n. So, when A
Hide()'s itself it needs the Show() B and vice-versa.
Normally, the top level window can do the hiding and showing, but in
this case there isn't one. It seems to me that the easiest solution
would be to add attributes to the wx.App :
...
This seems to solve the problem in a clean way. I can't think of any
hazards doing this since app is an object like any other python object.
Does anyone have more thoughts about this scheme ?
There's nothing particularly wrong with that. You could add a
"SwitchFrames" function to the App object to centralize it:
def ShowFrame( self, which ):
if which=='A':
self,frmB.Hide()
self.frmA.Show()
elif which=='B':
self,frmA.Hide()
self.frmB.Show()
That, at least, lets you hide the internals from the frames.
···
--
Tim Roberts, timr@probo.com
Providenza & Boekelheide, Inc.
I’ll add a simple list containing all the frames to app() and use the “which” argument in SwitchFrame() to show the given frame and hide all the rest if their IsShown() is True. ‘Keep it simple’ is a good way to go.
Thanks
Ray
I ended up choosing another scheme: Create a parent frame that is always invisible. It’s only function is to implement a kind of state machine that decides which of its 2 child Frames to display. This requires only 2 state flags per child window: The state machine clock is a wx.Timer running at only 20 ticks per second to keep it from eating up an excessive amount of CPU cycles.
The currently visible frame is responsible for setting the 2 flags for the next frame to become visible and also for hiding itself. This works well enough when there are only 2 frames that flip-flop to each other, but a better scheme could be implemented in the controller frame code.
···
On Wed, Jun 29, 2011 at 1:16 PM, Ray Pasco pascor22234@gmail.com wrote:
I’ll add a simple list containing all the frames to app() and use the “which” argument in SwitchFrame() to show the given frame and hide all the rest if their IsShown() is True. ‘Keep it simple’ is a good way to go.
#---------------------------------------------------------------------------
class InvisibleControllerFrame( wx.Frame ) :
def __init__( self ) :
# Size, position and appearance are irrelevant because it's always invisible !
wx.Frame.__init__( self, None, -1 )
#-----
# CreateGuiFrame( ... )
# CreateGrabFrame( ... )
self.showGuiFrameNow = True # Initially .Show() this Frame
self.guiFrameIsShown = False
self.showGrabFrameNow = False
self.grabFrameIsShown = False
#-----
self.ctrlrTimer = wx.Timer( self )
self.Bind( wx.EVT_TIMER, self.OnFrameDisplayTimer )
ticksPerSecond = 20 # a heuristically optimum rate
clockRate = 1000/ticksPerSecond
self.ctrlrTimer.Start( milliseconds=clockRate, oneShot=False )
#end __init__
#----------------------------------
def OnFrameDisplayTimer( self, event ) :
""" Invisible Frame display state machine
"""
if self.showGuiFrameNow and (not self.guiFrameIsShown) :
self.showGuiFrameNow = False # Execute .Show() only once ...
self.guiFrameIsShown = True # when self.showGuiFrameNow == True
self.guiFrame.Show()
elif self.showGrabFrameNow and (not self.grabFrameIsShown) :
self.showGrabFrameNow = False # Execute .Show() only once ...
self.grabFrameIsShown = True
self.grabFrame.Show()
elif (not self.guiFrameIsShown) and (not self.grabFrameIsShown) :
self.Destroy() # App.MainLoop exit
#end OnFrameDisplayTimer def
#end InvisibleControllerFrame class
#==============================================================================
(KISS in action…)
Ray Pasco