Gradient panel with transparent background StaticTexts - Flicker

466 views
Skip to first unread message

Dom Dom

unread,
Dec 6, 2010, 7:31:19 AM12/6/10
to wxpytho...@googlegroups.com
Hello All,

Attached is a small app that may be useful to others who don't like to re-invent the wheel !

It shows a gradient panel with some StaticTexts.
The problem with static texts and a gradient panel is that they usually appear with a rectangle of a different colour than the panel background.
So, the final result is not as nice as it could be.

Consequently, I think the example I give avoids this problem, although it is not perfect.
In the OnPaint method, I get the colour of the pixel located in the middle of the static text.
And I set the background colour of the static text to this average value.

I tried to avoid flickering, but when the window is manually resized, the flicker remains.
Could anybody try to solve this and explain the how to, if it is possible ?

Thanks in advance

Dominique
Gradient_panel_with_transparent_bckg_statictexts.py

Robin Dunn

unread,
Dec 6, 2010, 1:26:48 PM12/6/10
to wxpytho...@googlegroups.com

Do the same EVT_ERASE_BACKGROUND trick for the panel as you do for the
frame. Or use self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM) instead.


--
Robin Dunn
Software Craftsman
http://wxPython.org

Ray Pasco

unread,
Dec 6, 2010, 2:18:10 PM12/6/10
to wxpytho...@googlegroups.com
On Mon, Dec 6, 2010 at 7:31 AM, Dom Dom <mydo...@gmail.com> wrote:
Hello All,

Attached is a small app that may be useful to others who don't like to re-invent the wheel !
...

Dominique
 
You didn't state what is your platform or what versions of Python and wxPython you are using. This is very important to know. What works fine on one platform fails miserably on another. This is due to the different fundamental ways OS's handle graphics drawing. Fow example, MSW is particularly tolerant displaying DC's, in general. Perhaps wxPython has been tuned more for MS Windows platforms, or that MSW is simply more tolerant than others.
 
Only DC's specific to wx.EVT_PAINT evets should be used in wx.EVT_PAINT event handlers.
 
See the attached demo [ DC_Draw_Text_On_Gradient_BG_TEST.py ] that illustrates a good way to place text on a custom background. The other demo is a cleaned up and documented version of your own sample code.
 
I couldn't get the flicker to go away. I think the GridBagSizer may be causing excessive delays that may be slowing the redraws and, thus, causing the flicker flashes. But this happens only sometimes, which may have to do with the CPU's loading at the particular moment of the redarw. Or not. Try absolute positioning to this off-the-top-of-my-head theory.
 
Good luck, because large sized DC painting is generally a big PITA.
 
Ray Pasco
 
DC_Draw_Text_On_Gradient_BG_TEST.py
Gradient_panel_with_transparent_bckg_statictexts_MOD.py

C M

unread,
Dec 6, 2010, 2:32:31 PM12/6/10
to wxpytho...@googlegroups.com
On Mon, Dec 6, 2010 at 7:31 AM, Dom Dom <mydo...@gmail.com> wrote:
Hello All,

Attached is a small app that may be useful to others who don't like to re-invent the wheel !

It shows a gradient panel with some StaticTexts.
The problem with static texts and a gradient panel is that they usually appear with a rectangle of a different colour than the panel background.
So, the final result is not as nice as it could be.

Consequently, I think the example I give avoids this problem, although it is not perfect.
In the OnPaint method, I get the colour of the pixel located in the middle of the static text. 
And I set the background colour of the static text to this average value.

That's one way to go. 

I have worked on a different way--assuming that the static text doesn't need to change-- which is to remove the staticTextCtrl and just draw the same text over the gradient at the same location, and I have a most-working class to do that automatically.  I hope to at some point continue this and make these approaches available to the list.  It already (mostly) works for staticTexts, but I want it to work for anything that has a text-over-background part of it (checkbox, radiobutton, etc.), but I think that requires using generic versions of those, which I haven't gotten around to making, as I'm working on other stuff these days. 

I use wx.BufferedPaintDC and also the function at bottom, courtesy of Robin, to get things to not flicker.

Che

    def SetCompositeMode(self, on=True):
        #Necessary on Windows
        widget_frame = self.widget_parent.GetParent()
       # get the current extended syle bits
        exstyle = win32api.GetWindowLong(widget_frame.GetHandle(),
                                        win32con.GWL_EXSTYLE)
       # adjust it
        if on:
            exstyle |= win32con.WS_EX_COMPOSITED
        else:
            exstyle &= ~win32con.WS_EX_COMPOSITED
       # put it back
        win32api.SetWindowLong(widget_frame.GetHandle(),
                              win32con.GWL_EXSTYLE,
                              exstyle)



Dominique

unread,
Dec 6, 2010, 3:38:02 PM12/6/10
to wxPython-users
Hi Robin,

Excellent.
No more flicker !!

Thanks a lot

Dominique

Dominique

unread,
Dec 6, 2010, 3:44:56 PM12/6/10
to wxPython-users
Hi Ray,



On 6 déc, 20:18, Ray Pasco <pascor22...@gmail.com> wrote:
>
> You didn't state what is your platform or what versions of Python and
> wxPython you are using. This is very important to know. What works fine on
> one platform fails miserably on another. This is due to the different
> fundamental ways OS's handle graphics drawing. Fow example, MSW is
> particularly tolerant displaying DC's, in general. Perhaps wxPython has been
> tuned more for MS Windows platforms, or that MSW is simply more tolerant
> than others.

Windows 5.1.2600
Python 2.6.5 (r265:79096, Mar 19 2010, 21:48:26) [MSC v.1500 32 bit
(Intel)]
Wx 2.8.11.0

By the way, if people working on Mac or Linux can test the app to know
if it works, that would be great !

>
> Only DC's specific to wx.EVT_PAINT evets should be used in wx.EVT_PAINT
> event handlers.
>
> See the attached demo [ DC_Draw_Text_On_Gradient_BG_TEST.py ] that
> illustrates a good way to place text on a custom background. The other demo
> is a cleaned up and documented version of your own sample code.
Thanks for your demo and your remarks. I'll try to take care. It is
good to try to improve one's work !

> I couldn't get the flicker to go away. I think the GridBagSizer may be
> causing excessive delays that may be slowing the redraws and, thus, causing
> the flicker flashes. But this happens only sometimes, which may have to do
> with the CPU's loading at the particular moment of the redarw. Or not. Try
> absolute positioning to this off-the-top-of-my-head theory.

Robin's answer solves the problem

> Good luck, because large sized DC painting is generally a big PITA.
Thanks a lot Ray

Dominique

Robin Dunn

unread,
Dec 6, 2010, 4:18:30 PM12/6/10
to wxpytho...@googlegroups.com
On 12/6/10 12:44 PM, Dominique wrote:
> Hi Ray,

>
>
>
> On 6 d�c, 20:18, Ray Pasco<pascor22...@gmail.com> wrote:
>>
>> You didn't state what is your platform or what versions of Python and
>> wxPython you are using. This is very important to know. What works fine on
>> one platform fails miserably on another. This is due to the different
>> fundamental ways OS's handle graphics drawing. Fow example, MSW is
>> particularly tolerant displaying DC's, in general. Perhaps wxPython has been
>> tuned more for MS Windows platforms, or that MSW is simply more tolerant
>> than others.
>
> Windows 5.1.2600
> Python 2.6.5 (r265:79096, Mar 19 2010, 21:48:26) [MSC v.1500 32 bit
> (Intel)]
> Wx 2.8.11.0
>
> By the way, if people working on Mac or Linux can test the app to know
> if it works, that would be great !

It works well on Mac.

Dominique

unread,
Dec 6, 2010, 4:27:25 PM12/6/10
to wxPython-users
Thanks
Dominique

Ray Pasco

unread,
Dec 6, 2010, 10:00:53 PM12/6/10
to wxpytho...@googlegroups.com
What kind of magic is this ?!   (OK, I borrowed this line from a certain movie.)
 
Why does hooking into the event, doing absolutely nothing extra and then passing on the event processing do, exactly ?
 
Does this work on all platforms or just MSW ?
 
Ray
 

Robin Dunn

unread,
Dec 6, 2010, 11:19:26 PM12/6/10
to wxpytho...@googlegroups.com
On 12/6/10 7:00 PM, Ray Pasco wrote:
> On Mon, Dec 6, 2010 at 1:26 PM, Robin Dunn <ro...@alldunn.com

> Do the same EVT_ERASE_BACKGROUND trick for the panel as you do for


> the frame. Or use self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM) instead.
>
>
> --
> Robin Dunn
> Software Craftsman

> http://wxPython.org <http://wxpython.org/>


>
> What kind of magic is this ?! (OK, I borrowed this line from a certain
> movie.)
> Why does hooking into the event, doing absolutely nothing extra and then
> passing on the event processing do, exactly ?

By catching the event and not calling Skip then you are preventing the
default handler for the event from being called. In this case that
default handler is erasing the background, which is a major cause of
flicker if your paint handler is just going to fill the whole window
with something else. (First you see the cleared background, then you
see the painted window. TaDa! Flicker.)

> Does this work on all platforms or just MSW ?

MSW is usually the only one that needs it. In normal situations the
erase background event is simulated on the other platforms anyway, it's
not a separate event coming from the system.

Dominique

unread,
Dec 7, 2010, 12:48:46 PM12/7/10
to wxPython-users
Thank you for this clear explanation, Robin.
Dominique
Reply all
Reply to author
Forward
0 new messages