Image as a background to a form

Hi,

Is it possible to use an Image as a background to a form / frame / panel
and then load other controls (like a text box) on top of it? Can this
be achieved using transparency? Or is there a 'Z' order that can be used?

I tried fooling around with the ShapedWindow example in the demos but
was unable to load any control on it. I tried putting a button on top
of the penguin, but that didn't work. Perhaps I am doing something wrong.

I would appreciate it if someone could offer a little advice on how I
could use an image as a background to a form or better still, how I
could load controls on a ShapedWindow.

Best Regards
Feroze

···

=================
Jar Jar Binks will be Jedi!

Hi,

Is it possible to use an Image as a background to a form / frame / panel
and then load other controls (like a text box) on top of it? Can this
be achieved using transparency? Or is there a 'Z' order that can be used?

Capture EVT_PAINT and EVT_SIZE and use those to draw to a panel:

class MyPanel(wx.Panel):
    def __init__(self, parent, id):
        wx.Panel.__init__(self, parent, id)
        self.bitmap = wx.Bitmap('bitmap.png')
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.Bind(wx.EVT_SIZE, self.OnSize)

    def OnPaint(self, event):
        dc = wx.PaintDC(self)
        self.Draw(dc)

    def OnSize(self, event):
        dc = wx.ClientDC(self)
        self.Draw(dc)

    def Draw(self, dc):
        dc.DrawBitmap(self.bitmap, 0, 0)

I tried fooling around with the ShapedWindow example in the demos but
was unable to load any control on it. I tried putting a button on top
of the penguin, but that didn't work. Perhaps I am doing something wrong.

Perhaps some example code demonstrating what you were attempting? I've
used a wx.ShapedWindow as a regular frame successfully.

I would appreciate it if someone could offer a little advice on how I
could use an image as a background to a form or better still, how I
could load controls on a ShapedWindow.

This is based on some code I wrote using a ShapedWindow, but it's pretty
much straight from the demo. It's untested as is (I stripped a bunch of
app-specific code from it), but it should be pretty close:

class MyFrame(wx.Frame):
    def __init__(self, parent, id):
        wx.Frame.__init__(self, parent, id, '',
                          style = wx.FRAME_SHAPED | wx.SIMPLE_BORDER | wx.FRAME_NO_TASKBAR | wx.STAY_ON_TOP)
        self.image = wx.Bitmap('frame.png')
        self.width, self.height = self.image.GetWidth(), self.image.GetHeight()
        self.delta = (0, 0)
        self.hasShape = False
        self.SetClientSize((self.width, self.height))
        
        if wx.Platform == '__WXGTK__':
            rect = None
            self.Bind(wx.EVT_WINDOW_CREATE, self.SetWindowShape)
        else:
            rect = self.SetWindowShape()

        sizer = wx.BoxSizer(wx.HORIZONTAL)
        self.SetSizer(sizer)
        panel = wx.Panel(self, -1)
        sizer.Add(panel, 1, wx.EXPAND)

        ### Add any controls you want to the panel here

        self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
        self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
        self.Bind(wx.EVT_MOTION, self.OnMotion)
        self.Bind(wx.EVT_PAINT, self.OnPaint)

        if rect:
            self.SetSize((rect.width, rect.height))
        
    def OnPaint(self, event):
        dc = wx.PaintDC(self)
        self.Draw(dc)

    def Draw(self, dc):
        mdc = wx.MemoryDC()
        mdc.SelectObject(self.image)
        w, h = self.image.GetWidth(), self.image.GetHeight()
        dc.Blit(0, 0, w, h, mdc, 0, 0)

    def OnLeftDown(self, event):
        self.CaptureMouse()
        x, y = self.ClientToScreen(event.GetPosition())
        originx, originy = self.GetPosition()
        dx = x - originx
        dy = y - originy
        self.delta = ((dx, dy))

    def OnLeftUp(self, event):
        if self.HasCapture():
            self.ReleaseMouse()

    def OnMotion(self, event):
        if event.Dragging() and event.LeftIsDown():
            x, y = self.ClientToScreen(event.GetPosition())
            fp = (x - self.delta[0], y - self.delta[1])
            self.Move(fp)
        
    def SetWindowShape(self, event = None):
        r = wx.RegionFromBitmap(self.image)
        self.hasShape = self.SetShape(r)
        return r.GetBox()

Regards,
Cliff

···

On Mon, 2004-09-06 at 17:50, Feroze Arif wrote:

--
Cliff Wells <clifford.wells@comcast.net>

Cliff Wells wrote:

···

On Mon, 2004-09-06 at 17:50, Feroze Arif wrote:

Hi,

Is it possible to use an Image as a background to a form / frame / panel
and then load other controls (like a text box) on top of it? Can this
be achieved using transparency? Or is there a 'Z' order that can be used?

Capture EVT_PAINT and EVT_SIZE and use those to draw to a panel:

A little better in this case is to use EVT_ERASE_BACKGROUND as shown in the ColourDB.py sample in the demo. Look at OnEraseBackground and TileBackground.

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

Feroze Arif wrote:

Hi,

Is it possible to use an Image as a background to a form / frame / panel
and then load other controls (like a text box) on top of it? Can this
be achieved using transparency? Or is there a 'Z' order that can be used?

I tried fooling around with the ShapedWindow example in the demos but
was unable to load any control on it. I tried putting a button on top
of the penguin, but that didn't work. Perhaps I am doing something wrong.

I would appreciate it if someone could offer a little advice on how I
could use an image as a background to a form or better still, how I
could load controls on a ShapedWindow.

Best Regards
Feroze

In a similar vein, I was hoping to be able to draw a wxTextCtrl on top of another control and have the background be invisible. I tried overriding EraseBackground for the wxTextCtrl, but it still drew the background.

Attached is a small script that I wrote (using wx2.4 on windows) that seems to almost do what I want. One of the controls (txtTest) can be moved around the screen by using the right mouse button. The other is a custom control I was working on.

Is there any other way to do this? Really all I want is to have wxTextCtrl not draw the background in OnPaint. I think it does it because that is how it does highlighting, but I don't know that for sure.

Basically, what I really want is just the ability to write arbitrary text to the screen that someone can select and copy. As near as I can tell only wxTextCtrl allows that, so I'm trying to start from there.

Thanks,
John
=:->

TestDlg.py (6.69 KB)

test.png

John Meinel wrote:

In a similar vein, I was hoping to be able to draw a wxTextCtrl on top of another control and have the background be invisible. I tried overriding EraseBackground for the wxTextCtrl, but it still drew the background.

The native control is probably drawing the text with the native equivalent of wx.DC.SetBackgroundMode(wx.SOLID). We probably can't do anyting about that.

···

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