Splash screen refresh issue

OK –
the full code is now……

···

class
SplashScreen(wx.Frame):

“”" Splash screen configured so that it destroys once the main

Idle page fram has instigated or if the timer times out."""

def init(self, bmp, timeout=20000):

self.bmp = bmp

style= wx.FRAME_SHAPED | wx.STAY_ON_TOP | wx.FRAME_NO_TASKBAR

wx.Frame.init(self, None, -1, “”, style=style)

mask = wx.Mask(self.bmp, wx.WHITE)

self.bmp.SetMask(mask)

self.reg = wx.RegionFromBitmap(self.bmp)

self.SetShape(self.reg)

#Starts The Timer. Once Expired, Splash Is Destroyed

self._splashtimer = wx.PyTimer(self.Close)

self._splashtimer.Start(timeout)

Set The Splash Size To The Bitmap Size

w = self.bmp.GetWidth()

h = self.bmp.GetHeight()

self.SetSize((w, h))

Bind the close event and display the screen

self.Bind(wx.EVT_CLOSE, self.CloseTest)

self.Bind(wx.EVT_PAINT, self.OnPaint)

self.CenterOnScreen()

self.Show()

def OnPaint(self, event):

“”" Handles The wx.EVT_PAINT For AdvancedSplash.
“”"

dc = wx.PaintDC(self)

Here We Redraw The Bitmap Over The Frame

dc.DrawBitmap(self.bmp, 0, 0, True)

wx.SafeYield()

event.Skip()

def CloseTest(self,event):

“”" Closing

“”"

app.frConsole.Show()

event.Skip()



and the final problem is one of timing. The applications following the
splash screen kick in immediately after the splash screen is called.
Something along the lines of :-

if
name == ‘main’:

app=SpinnakerApp()

app.createSplashScreen()

app.startServer()

app.createConsole()

app.startDatabase()

#wxi.InspectionTool().Show()

app.MainLoop()

Now
once the server code kicks in the full paint of the splash screen is
interrupted and you can have the original greyed out image for anything up to 2
-3 seconds before the paint event fully runs its course. How may I hold
off following applications in order to first of all get a full paint of the splash
screen. I have tried removing the yield command in order that
the splash screen holds on to processing power long enough to paint the bitmap,
but that doesn’t help.

Thanks
in advance

  • David

No virus found in this outgoing message.

Checked by AVG Free Edition.

Version: 7.5.516 / Virus Database: 269.17.13/1206 - Release Date: 01/01/2008 12:09

David Poundall wrote:

Now once the server code kicks in the full paint of the splash screen is interrupted and you can have the original greyed out image for anything up to 2 -3 seconds before the paint event fully runs its course. How may I hold off following applications in order to first of all get a full paint of the splash screen. I have tried removing the yield command in order that the splash screen holds on to processing power long enough to paint the bitmap, but that doesn’t help.

#1 rule in GUI programming (well, 2nd one, after "Choose wxPython" <wink!>) is to never block the GUI thread. If you stop the flow of control from getting into or getting back to the MainLoop then events (like the paint events for the splash screen) will not be delivered to their handlers.

See LongRunningTasks - wxPyWiki

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

> Robin Wrote:
> #1 rule in GUI programming (well, 2nd one, after "Choose wxPython"
> <wink!>) is to never block the GUI thread. If you stop the flow of
> control from getting into or getting back to the MainLoop then events
> (like the paint events for the splash screen) will not be delivered to
> their handlers.
>
> See LongRunningTasks - wxPyWiki
>
David Wrote:
Clean forgot about that one Robin, thanks for the polite poke.

On a final note to do with splash screens, the difference between these two
splash screen codes ...

---------------------------------------- (1)
class SplashScreen(wx.SplashScreen):
    """ Splash screen configured so that it destroys once the main
    Console frame has built up or if the timer times out.
    """
    def __init__(self, bmp, timeout=20000):
        wx.SplashScreen.__init__(self, bmp, wx.SPLASH_CENTRE_ON_SCREEN |
wx.SPLASH_TIMEOUT, timeout,
                None, -1, style = wx.SIMPLE_BORDER | wx.FRAME_NO_TASKBAR |
wx.STAY_ON_TOP)
        wx.Yield()
        self.Bind(wx.EVT_CLOSE, self.CloseTest)
    
    def CloseTest(self,event):
        app.frConsole.Show()
        event.Skip()

---------------------------------------- (2)
class SplashScreen00(wx.Frame):
    """ Splash screen configured so that it destroys once the main
    Console frame has built up or if the timer times out.
    """
    def __init__(self, bmp, timeout=20000):

        self.bmp = bmp
        pos=wx.DefaultPosition
        size=wx.DefaultSize
        style= wx.FRAME_SHAPED | wx.STAY_ON_TOP | wx.FRAME_NO_TASKBAR
        
        wx.Frame.__init__(self, None, -1, "", pos, size, style)
        
        mask = wx.Mask(self.bmp, wx.WHITE)
        self.bmp.SetMask(mask)
        self.reg = wx.RegionFromBitmap(self.bmp)
        self.SetShape(self.reg)
        
        #Starts The Timer. Once Expired, AdvancedSplash Is Destroyed
        self._splashtimer = wx.PyTimer(self.Close)
        self._splashtimer.Start(timeout)

        # Set The AdvancedSplash Size To The Bitmap Size
        w = self.bmp.GetWidth()
        h = self.bmp.GetHeight()
        self.SetSize((w, h))
     
        # Bind the close event and display the screen
        self.Bind(wx.EVT_CLOSE, self.CloseTest)
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.CenterOnScreen()
        self.Show()
  
    def OnPaint(self, event):
        """ Handles The wx.EVT_PAINT For AdvancedSplash. """
        dc = wx.PaintDC(self)
        # Here We Redraw The Bitmap Over The Frame
        dc.DrawBitmap(self.bmp, 0, 0, True)
        wx.SafeYield()
        event.Skip()
        
    def CloseTest(self,event):
        """ Closing
        """
        app.frConsole.Show()
        event.Skip()

···

-----------------------------------------------------
... appears to be that the second code has an OnPaint.

If you add an EVT_SHOW event to both classes you find that the Show event
will fire twice throughout the lifetime of the wx.Frame based class (once on
‘self.SetShape(self.reg)’ and once on the ‘onPaint’ event), but only once on
the wx.SplashScreen class. The latter only being a single bitmap display
event anyway.

You can see from the nature of the above two splash screen classes, the on
close event fires a show event of a second frame called console. Console is
building in the background while splash screen is displaying, and at some
point after it has been built it is shown by closing the splash screen
class.

When this works the jump from the splash screen to the console screen is
clean and quick, which is the desired effect.

It works for the wx.Splashscreen based class but not for the wx.Frame based
class. The second paint for the latter class is interfered with by the
build events going off in the background. As Robin says, don’t block the
main GUI thread.

The advantage of the wx.Frame based class is that a Bitmap mask can be used
on the frame – and that is the only advantage. IF a .png were used with a
transparent layer instead, the wx.Frame approach may well be able to be
written so that it too uses only a single show event, and then it too would
work. I don’t have a .png set up like this so I can’t check it out.

For my own part I am going to run with the wx.SplashScreen class for now.
It was a useful exercise for me to explore frame interactions at the start
of a program.

I hope that by posting this at least one person will be able to leverage my
time in some way.

If I have made any sweeping statements in the above that are incorrect or
misleading in any way I apologise for my wxPython newbieness and look
forward to the clip round the ear that will no doubt slap me down and put me
back on track :wink:

- David

PS You can’t run the console build in it’s own thread because it is then not
in the main GUI thread, you get messaging conflicts, and I think that this
breaks Robins Third rule.

No virus found in this outgoing message.
Checked by AVG Free Edition.
Version: 7.5.516 / Virus Database: 269.17.13/1207 - Release Date: 02/01/2008
11:29

David Poundall wrote:

Robin Wrote:
#1 rule in GUI programming (well, 2nd one, after "Choose wxPython"
<wink!>) is to never block the GUI thread. If you stop the flow of
control from getting into or getting back to the MainLoop then events
(like the paint events for the splash screen) will not be delivered to
their handlers.

See LongRunningTasks - wxPyWiki

David Wrote:
Clean forgot about that one Robin, thanks for the polite poke.

On a final note to do with splash screens, the difference between these two
splash screen codes ...

[...]

... appears to be that the second code has an OnPaint.

So does the first class, it just happens to be in the base class instead of yours.

The advantage of the wx.Frame based class is that a Bitmap mask can be used
on the frame – and that is the only advantage. IF a .png were used with a
transparent layer instead, the wx.Frame approach may well be able to be
written so that it too uses only a single show event, and then it too would
work. I don’t have a .png set up like this so I can’t check it out.

The frame would still be behind the png image, so even if it has translucent areas all you would see would be the frame's background, not the desktop. There are ways to do that, but they are not covered by the wx API yet.

PS You can’t run the console build in it’s own thread because it is then not
in the main GUI thread, you get messaging conflicts, and I think that this
breaks Robins Third rule.

Hmm... m'thinks I should start writing these down...

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

I could see that the sw.Splashscreen will be subclassed from a wx.Frame at
some point, so I am not surprised to here you say that. So... it must be
that either :

1. The Wx.Frame code is doing something that the wx.Splashscreen isn't
causing processing to be released before it should be ie. before the frame
is fully drawn.

2. Or ... you must be using the wx.Magic class somewhere in the
wx.Splashscreen code. Problem is I can't seem to find much documentation on
wx.Magic at all :wink:

Or a combination of the 2.

Thank you for responding on this Robin. Time for me to start to arm wrestle
with MySQL for a while now I think.

- David

No virus found in this outgoing message.
Checked by AVG Free Edition.
Version: 7.5.516 / Virus Database: 269.17.13/1207 - Release Date: 02/01/2008
11:29

···

-----Original Message-----
From: Robin Dunn [mailto:robin@alldunn.com]
Sent: 03 January 2008 17:51
To: wxPython-users@lists.wxwidgets.org
Subject: Re: [wxPython-users] Splash screen refresh issue

David Poundall wrote:
>>> Robin Wrote:
>>> #1 rule in GUI programming (well, 2nd one, after "Choose wxPython"
>>> <wink!>) is to never block the GUI thread. If you stop the flow of
>>> control from getting into or getting back to the MainLoop then events
>>> (like the paint events for the splash screen) will not be delivered to
>>> their handlers.
>>>
>>> See LongRunningTasks - wxPyWiki
>>>
>> David Wrote:
>> Clean forgot about that one Robin, thanks for the polite poke.
>>
>
> On a final note to do with splash screens, the difference between these
two
> splash screen codes ...
>
[...]
> ... appears to be that the second code has an OnPaint.

So does the first class, it just happens to be in the base class instead
of yours.