static text and transparent background

Hi,
I'm trying to create a program that has an image like background and
some static text widgets into it. I try with OnPaint event for draw the
bg image (and this work well), but when I put a statictext into it, I
see that the background are that of the static (so gray), and not of my
image, so I tried with OnPaint / EraseBackground methods of the static,
but all without fortune...
In the better case I can draw myself the text of the StaticText into the
PaintDc, but the background are that of the window under! (I think that
wx don't paint the rect of the widget)

What can I do? There is a already done widget that do this?

Thanks,
Michele

Hello Michele,

In the better case I can draw myself the text of the
StaticText into the PaintDc, but the background are that of
the window under! (I think that wx don't paint the rect of the widget)

That is be the way I would go for it... Does the look changes if you add:

dc.SetBackgroundMode(wx.TRANSPARENT)

Before drawing the text in the OnPaint()?

Andrea.

···

_________________________________________
Andrea Gavana (gavana@kpo.kz)
Reservoir Engineer
KPDL
4, Millbank
SW1P 3JA London

Direct Tel: +44 (0) 20 717 08936
Mobile Tel: +44 (0) 77 487 70534
Fax: +44 (0) 20 717 08900
Web: http://xoomer.virgilio.it/infinity77
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

That is be the way I would go for it... Does the look changes
if you add:

Sorry for the spaghetti english, I must be blind or someone must have put some LSD in my lunch today :smiley:

Andrea.

···

_________________________________________
Andrea Gavana (gavana@kpo.kz)
Reservoir Engineer
KPDL
4, Millbank
SW1P 3JA London

Direct Tel: +44 (0) 20 717 08936
Mobile Tel: +44 (0) 77 487 70534
Fax: +44 (0) 20 717 08900
Web: http://xoomer.virgilio.it/infinity77
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

Gavana, Andrea wrote:

Hello Michele,

In the better case I can draw myself the text of the StaticText into the PaintDc, but the background are that of the window under! (I think that wx don't paint the rect of the widget)

That is be the way I would go for it... Does the look changes if you add:

dc.SetBackgroundMode(wx.TRANSPARENT)

Before drawing the text in the OnPaint()?

Already tried, but the same. If you want I can create a small app for show the problem.

Andrea.

Ciao, :slight_smile:
Michele

Hello Michele,

Already tried, but the same.

Uhm, this seems strange to me, it is exactly the same thing I am doing with CustomTreeCtrl, that supports a background image. The text I draw has a transparent background. Well, I am not using dc.DrawText() but dc.DrawLabel()... However I don't see such big differences between the 2 methods.

If you want I can create a small
app for show the problem.

Yes, that would be the best option... Just to let us play with something :smiley:

Ciao!

Andrea.

···

_________________________________________
Andrea Gavana (gavana@kpo.kz)
Reservoir Engineer
KPDL
4, Millbank
SW1P 3JA London

Direct Tel: +44 (0) 20 717 08936
Mobile Tel: +44 (0) 77 487 70534
Fax: +44 (0) 20 717 08900
Web: http://xoomer.virgilio.it/infinity77
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

Michele Petrazzo wrote:

Gavana, Andrea wrote:

Hello Michele,

In the better case I can draw myself the text of the StaticText into the PaintDc, but the background are that of the window under! (I think that wx don't paint the rect of the widget)

That is be the way I would go for it... Does the look changes if you add:

dc.SetBackgroundMode(wx.TRANSPARENT)

Before drawing the text in the OnPaint()?

Already tried, but the same. If you want I can create a small app for show the problem.

A co-worker and I spent a couple of days earlier this summer experimenting with trying to create various transparent controls in an app. We got a few things to work sometimes, but then found that the behavior varied based on the video system in the computer (different video cards on the same operating system) so we dropped it. Basically, if you don't want your app to look like a platform-native application, you have to draw EVERYTHING yourself. So far, we've ended up creating listbox, checkbox, and static text controls on top of a wxPanel to get the appearance and behavior we want (and even there we've dropped the idea of transparency).

The frustrating part is that it's not possible to get sufficient information on appearance from most wxControls to render them yourself. You have to recreate all the behavior logic as well. This may be the fault of the underlying platform APIs -- but it would be nice to be able to have (for example) a wx.ListBox that does everything except paint itself. It's not very much fun to create a working ListBox from scratch.

    Kent

Hello Kent,

The frustrating part is that it's not possible to get
sufficient information on appearance from most wxControls to
render them yourself.
You have to recreate all the behavior logic as well. This may
be the fault of the underlying platform APIs -- but it would
be nice to be able to have (for example) a wx.ListBox that
does everything except paint itself. It's not very much fun
to create a working ListBox from scratch.

This goes in favour of a "skinnable" wxPython (wxWidgets?!?!), and it is somewhat contradictory wrt the underlying philosophy of wx*. However, I can perfectly understand what you feel, because every time I needed a new/different control, I had to redo everything from scratch, which is a little bit frustrating. If you need an existing control with different appearance, the best choice you have (a part of redoing *all* the job from scratch) is to look if a generic/common implementation of that control exists in the wxWidgets source tree. At least, you can translate the C++ code to Python instead of re-thinking the event/paint/size strategies from scratch. Otherwise, it is a PITA of trial and error until you get what you need :smiley:

Andrea.

···

_________________________________________
Andrea Gavana (gavana@kpo.kz)
Reservoir Engineer
KPDL
4, Millbank
SW1P 3JA London

Direct Tel: +44 (0) 20 717 08936
Mobile Tel: +44 (0) 77 487 70534
Fax: +44 (0) 20 717 08900
Web: http://xoomer.virgilio.it/infinity77
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

Gavana, Andrea wrote:

If you want I can create a small app for show the problem.

Yes, that would be the best option... Just to let us play with something :smiley:

The code is attached.
Put an image (image.jpg according to the code) on the same directory and
execute. You'll see the drawn text on the top left, but the background
are that of your above window (or the desktop). Try to maximize and
reduce the app, and you'll see the problem!

P.s. I see this problem only on win... On linux all work!

Ciao!

Andrea.

Michele

draw_example.py (2.29 KB)

Hello Michele,

Try not to use a wx.StaticText: simply draw the text in the OnPaint of your panel, like this:

import wx

class frame(wx.Frame):
    
    def __init__(self):
        
        wx.Frame.__init__(self, None, style= wx.DEFAULT_FRAME_STYLE)
        
        self._p = wx.Panel(self)
        self.mytext = "A LOT BIG TEXT"
        
        #Event bind
        self._p.Bind(wx.EVT_PAINT, self.onPaint)
        self._p.Bind(wx.EVT_SIZE, self.OnSize)
        self._p.Bind(wx.EVT_ERASE_BACKGROUND, self._DoEraseBG)
        
        #Image
        self._bmp = wx.Bitmap("./image.jpg")
        self._currentBmpSize = self._bmp.GetSize()
        self._p._bmp = self._bmp
        #Show
        self.Show()

    def _DoEraseBG(self, evt):
        """
        """
        #print "erase"
    
    def onPaint(self, evt):
        print "panint frame"
        dc = wx.BufferedPaintDC(self._p)
        
        dc.DrawBitmap(self._bmp, 0,0)

        dc.SetBackgroundMode(wx.TRANSPARENT)
        dc.SetFont(wx.Font(40, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL,
                           wx.FONTWEIGHT_NORMAL))
        dc.DrawText(self.mytext, 20, 20)
        
        evt.Skip()
    
    def OnSize(self, evt):
        size = self.GetClientSize()
        if size != self._currentBmpSize:
            img = wx.ImageFromBitmap(self._bmp).Scale(*size)
            self._bmp = wx.BitmapFromImage(img)
            
def main():
    app = wx.PySimpleApp()
    f = frame()
    app.MainLoop()

if __name__ == "__main__":
    main()

HTH.

Andrea.

···

_________________________________________
Andrea Gavana (gavana@kpo.kz)
Reservoir Engineer
KPDL
4, Millbank
SW1P 3JA London

Direct Tel: +44 (0) 20 717 08936
Mobile Tel: +44 (0) 77 487 70534
Fax: +44 (0) 20 717 08900
Web: http://xoomer.virgilio.it/infinity77
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

Gavana, Andrea wrote:

Hello Michele,

Try not to use a wx.StaticText: simply draw the text in the OnPaint of your panel, like this:

You are clever :slight_smile:
I know that method, but for my app I want, if I can of course, use a wxStaticText. If there isn't this possibility I'll use your!

Thanks,
Michele

I know that method, but for my app I want, if I can of
course, use a wxStaticText. If there isn't this possibility
I'll use your!

Have you tried with wx.lib.stattext.GenStaticText or whatever is its name? You may have more luck with that, but I have no idea :smiley:
Robin will now for sure what you could do to implement your idea, I just run out of intelligent/insightful comments :wink:

Andrea.

···

_________________________________________
Andrea Gavana (gavana@kpo.kz)
Reservoir Engineer
KPDL
4, Millbank
SW1P 3JA London

Direct Tel: +44 (0) 20 717 08936
Mobile Tel: +44 (0) 77 487 70534
Fax: +44 (0) 20 717 08900
Web: http://xoomer.virgilio.it/infinity77
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

Gavana, Andrea wrote:

I know that method, but for my app I want, if I can of course, use a wxStaticText. If there isn't this possibility I'll use your!

Have you tried with wx.lib.stattext.GenStaticText or whatever is its name?

Just now

You may have more luck with that, but I have no idea :smiley:

Still the same.

Robin will now for sure what you could do to implement your idea,

I hope that!

I just run out of intelligent/insightful comments :wink:

All the help are welcome, always!

Andrea.

Ciao,
Michele

Michele Petrazzo wrote:

P.s. I see this problem only on win... On linux all work!

Because on Linux the wx.StaticText does internally what Andrea is suggesting you do, it draws the text directly on the parent.

···

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

Gavana, Andrea wrote:

I know that method, but for my app I want, if I can of course, use
a wxStaticText. If there isn't this possibility I'll use your!

Have you tried with wx.lib.stattext.GenStaticText or whatever is its
name? You may have more luck with that, but I have no idea :smiley:

Probably not, since it still has a real widget, and it will default its background to a solid colour.

Robin
will now for sure what you could do to implement your idea, I just
run out of intelligent/insightful comments :wink:

If you really want to have a static text widget then a good generic approach is you can draw its background the same as the parent, just calculate the portion of the image that should be shown where the static text is located, and draw that portion on the background. You'll probably want to derive a class from wx.lib.stattext.GenStaticText to do this.

···

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