[wxPython-users] Scrolling text overlay

Mike Rooney mxr at qvii.com
Tue Apr 3 12:41:52 PDT 2007


Robin Dunn wrote:
> Mike Rooney wrote:
>> Hi everyone,
>>
>> I am wondering if I can use wxPython to display a scrolling text =

>> "banner" across a certain part of the screen. I don't think coding =

>> the scrolling would be the problem; my main issue is getting text =

>> with a transparent background "overlayed" on top of the users screen. =

>> I see that you can do transparent/shaped splash windows so I was =

>> wondering if I can use this somehow.
>>
>> Another alternative I suppose could be using PIL to generate images =

>> of the text with transparent backgrounds but that seems like it could =

>> be slow.
>>
>> Has anyone done anything similar to this and could lead me to an =

>> example, or suggestions? This will only be used on MSW, by the way.
>
> Shaped windows basically work by setting a region of the frame that =

> should be transparent, and one way to get the region is from the mask =

> of a bitmap.  So you can create a memory DC, fill it with a certain =

> color, draw your text to the bitmap, destroy the dc and then set the =

> bitmap's mask to be the fill color.  Then you can set the frame's =

> shape from the mask/region of the bitmap and then draw that bitmap in =

> the frame's EVT_PAINT handler.  When you want to scroll the text =

> you'll need to do the whole thing again.
>
Thanks. I had never created an EVT_PAINT handler, used any kind of DC, =

or done any work with masks for bitmaps but surprisingly, somehow, I got =

it to work! There is just one tiny little kink to work out; once the =

text has scrolled completely outside of the frame, the frame reappears. =

What I need to do is figure out the pixel width of the text I am =

scrolling, and if the textOffset =3D=3D textWidth, stop the timer. Any idea =

of how to do this? You will see my comment at the bottom of the onTimer =

method in the attached runnable sample. Thanks for all your help so far!

By the way, if I am doing anything in a silly way please let me know.

- Mike
-------------- next part --------------
import wx

class ShapedText(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(self, None, style =3D
                wx.FRAME_SHAPED | wx.SIMPLE_BORDER | wx.FRAME_NO_TASKBAR | =
wx.STAY_ON_TOP)
                =

        #make the background color white so it becomes transparent
        self.SetBackgroundColour(wx.WHITE)
        =

        #set up the timer which will move the text and paint the screen
        self.timer =3D wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.onTimer, source=3Dself.timer)
        self.timer.Start(15)
        =

        #make sure we are using our custom paint handler
        self.Bind(wx.EVT_PAINT, self.onPaint)
        =

        #create the bitmap
        self.bmp =3D wx.EmptyBitmap(200, 100)
        self.textOffset =3D 0
        self.setWindowShape()
        =

    def setWindowShape(self):
        # Use the bitmap's mask to determine the region
        r =3D wx.RegionFromBitmap(self.bmp)
        self.hasShape =3D self.SetShape(r)
        =

    def onPaint(self, event):
        # Draw the bitmap on the screen
        dc =3D wx.PaintDC(self)
        dc.DrawBitmap(self.bmp, 0,0, True)
        =

    def onTimer(self, event):
        # Draw the text on the bitmap, set a mask, and paint
        memDC =3D wx.MemoryDC(self.bmp)
        memDC.SetPen(wx.WHITE_PEN)
        memDC.SetBrush(wx.WHITE_BRUSH)
        memDC.DrawRectangle(0, 0, 200, 100) #is there a better way to just =
fill it?
        memDC.SetFont(wx.Font(24, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMA=
L, wx.FONTWEIGHT_NORMAL))
        memDC.DrawText("HELLO!", 200-self.textOffset, 2)
        memDC.Destroy()
        =

        mask =3D wx.Mask(self.bmp, wx.WHITE)
        self.bmp.SetMask(mask)
        =

        self.textOffset +=3D 1
        self.setWindowShape()
        self.Refresh()
        =

        #somehow I need to detect when the text is completely
        #off of the bitmap. how do I get the width of the text
        #I drew?
        #if self.textOffset =3D=3D ???:
        #    self.timer.Stop()
        =

        =

if __name__ =3D=3D "__main__":
    app =3D wx.PySimpleApp()
    frame =3D ShapedText()
    frame.Show(True)
    app.MainLoop()


More information about the wxpython-users mailing list