Generic graphical/drawing wxpython question

Hi,

Is there a class of controls in wxpython that allows an image button
no matter what the shape is where the bitmap loaded is the actual
button?
Meaning by that, i do not want a generic/native square or round button
drawn with the bitmap drawn on it, i just want to load a bitmap and
have it be the button. Clicking on the bitmap would send a wx.Button
evt or radio evt etc...

If not, can it be done by subclassing any of the existing controls
classes or window class? Which one would be best to start from?

Finally does wx.Bitmap support alpha/transparency? I always seem to
lose the transparency of the background going from a wx.Image to a
wx.Bitmap.
I am not sure if i am losing transparency or if i am just seeing the
background native/generic button underneath it. It might be the
latter.

Any help here would be greatly appreciated,

Thank you

VC

Is there a class of controls in wxpython that allows an image button
no matter what the shape is where the bitmap loaded is the actual
button?
Meaning by that, i do not want a generic/native square or round button
drawn with the bitmap drawn on it, i just want to load a bitmap and
have it be the button.

not entirely sure what yo mean, but I think there is a GenStaticBitmap
or something like that.

Clicking on the bitmap would send a wx.Button
evt or radio evt etc...

It won't get you an EVT_BUTTON, but it does catch the mouse events, so
you could catch those.

I also recently wrote a class for a custom app that puts a bunch of
bitmaps on a panel, and attaches events to them -- essentially custom
bitmap buttons. In this case, they images are round (the visiblepart,
anyway), so the click-able region is round, too.

It was pretty straight-forward.

-Chris

If not, can it be done by subclassing any of the existing controls
classes or window class?

That's what GenStaticBitmap does -- but are you sure that
GenBitmapButton doesn't work for you? YOu can customize how that
renders if need be.

-Chris

Which one would be best to start from?

···

On Tue, May 1, 2012 at 3:35 PM, VC <napoleonics@gmail.com> wrote:

Finally does wx.Bitmap support alpha/transparency? I always seem to
lose the transparency of the background going from a wx.Image to a
wx.Bitmap.
I am not sure if i am losing transparency or if i am just seeing the
background native/generic button underneath it. It might be the
latter.

Any help here would be greatly appreciated,

Thank you

VC

--
To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com
or visit http://groups.google.com/group/wxPython-users?hl=en

--

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

Thanks for the answer. The Generic bitmap button class is pretty good
and straight forward but i cannot seem to be able to get a button
other than square or rectangular and keep the transparency.
So let's say i have a png image with a round button and transparent
square background, using the GenBitmapButton i still see the square
background as a shade of white. I am not sure if in the conversion
from a wx.Image to a wx.Bitmap i lose the alpha channel or if the
class draws a button in the background and puts the bitmap on it and
that is why i see a square button underneath my round button.

I hope this was clear.

I want to be able to put a bitmap of any shape as a button and have
the functionality of buttons.

VC

···

On May 1, 6:03 pm, Chris Barker <chris.bar...@noaa.gov> wrote:

On Tue, May 1, 2012 at 3:35 PM, VC <napoleon...@gmail.com> wrote:
> Is there a class of controls in wxpython that allows an image button
> no matter what the shape is where the bitmap loaded is the actual
> button?
> Meaning by that, i do not want a generic/native square or round button
> drawn with the bitmap drawn on it, i just want to load a bitmap and
> have it be the button.

not entirely sure what yo mean, but I think there is a GenStaticBitmap
or something like that.

> Clicking on the bitmap would send a wx.Button
> evt or radio evt etc...

It won't get you an EVT_BUTTON, but it does catch the mouse events, so
you could catch those.

I also recently wrote a class for a custom app that puts a bunch of
bitmaps on a panel, and attaches events to them -- essentially custom
bitmap buttons. In this case, they images are round (the visiblepart,
anyway), so the click-able region is round, too.

It was pretty straight-forward.

-Chris

> If not, can it be done by subclassing any of the existing controls
> classes or window class?

That's what GenStaticBitmap does -- but are you sure that
GenBitmapButton doesn't work for you? YOu can customize how that
renders if need be.

-Chris

Which one would be best to start from?

> Finally does wx.Bitmap support alpha/transparency? I always seem to
> lose the transparency of the background going from a wx.Image to a
> wx.Bitmap.
> I am not sure if i am losing transparency or if i am just seeing the
> background native/generic button underneath it. It might be the
> latter.

> Any help here would be greatly appreciated,

> Thank you

> VC

> --
> To unsubscribe, send email to wxPython-users+unsubscribe@googlegroups.com
> or visithttp://groups.google.com/group/wxPython-users?hl=en

--

Christopher Barker, Ph.D.
Oceanographer

Emergency Response DivisionNOAA/NOS/OR&R (206) 526-6959begin_of_the_skype_highlighting (206) 526-6959 voice7600 Sand Point Way NE (206) 526-6329begin_of_the_skype_highlighting (206) 526-6329 faxSeattle, WA 98115 (206) 526-6317begin_of_the_skype_highlighting (206) 526-6317 main reception

Chris.Bar...@noaa.gov

I want to be able to put a bitmap of any shape as a button and have
the functionality of buttons.

You can do this by binding wx.EVT_LEFT_UP to a wx.StaticBitmap and
then doing whatever you want this "button" to do in the event handler.
If you really want it to look like a (round) button, you could write
extra code to swap the bitmaps used between a "pressed" or "unpressed"
state.

Did you look at ButtonPanel in the Demo? That's what he's doing, I believe.

Che

It is a widget. A widget is rectangular. A widget has a background. The widget's parent's paint is clipped to exclude the child widgets, IOW that portion of the parent is not even being drawn under normal circumstances (and leads to flicker if you force it.) These are pretty much inescapable facts of life in wx.

If you want a non-rectangular thing in which the parent's content shows through then you either have to fake it by redrawing that portion of the parent's content on the background of the child, or you need to not use a child widget at all and instead draw something that looks like a button directly on the parent and make the parent able to handle the mouse and keyboard events for it, and send events in response.

···

On 5/1/12 4:38 PM, VC wrote:

Thanks for the answer. The Generic bitmap button class is pretty good
and straight forward but i cannot seem to be able to get a button
other than square or rectangular and keep the transparency.
So let's say i have a png image with a round button and transparent
square background, using the GenBitmapButton i still see the square
background as a shade of white. I am not sure if in the conversion
from a wx.Image to a wx.Bitmap i lose the alpha channel or if the
class draws a button in the background and puts the bitmap on it and
that is why i see a square button underneath my round button.

--
Robin Dunn
Software Craftsman

Thanks Robin, that clears it up for me. So you are saying that if i
need anything non rectangular i need to use the wx.StaticBitmap as
suggested by others and make the bindings myself.
The background of a button widget cannot be made transparent? like the
wx.TANSPARENT_WINDOW?

VC

···

On May 1, 7:56 pm, Robin Dunn <ro...@alldunn.com> wrote:

On 5/1/12 4:38 PM, VC wrote:

> Thanks for the answer. The Generic bitmap button class is pretty good
> and straight forward but i cannot seem to be able to get a button
> other than square or rectangular and keep the transparency.
> So let's say i have a png image with a round button and transparent
> square background, using the GenBitmapButton i still see the square
> background as a shade of white. I am not sure if in the conversion
> from a wx.Image to a wx.Bitmap i lose the alpha channel or if the
> class draws a button in the background and puts the bitmap on it and
> that is why i see a square button underneath my round button.

It is a widget. A widget is rectangular. A widget has a background. The
widget's parent's paint is clipped to exclude the child widgets, IOW
that portion of the parent is not even being drawn under normal
circumstances (and leads to flicker if you force it.) These are pretty
much inescapable facts of life in wx.

If you want a non-rectangular thing in which the parent's content shows
through then you either have to fake it by redrawing that portion of the
parent's content on the background of the child, or you need to not use
a child widget at all and instead draw something that looks like a
button directly on the parent and make the parent able to handle the
mouse and keyboard events for it, and send events in response.

--
Robin Dunn
Software Craftsmanhttp://wxPython.org

Thanks for the answer. The Generic bitmap button class is pretty good
and straight forward but i cannot seem to be able to get a button
other than square or rectangular and keep the transparency.
So let's say i have a png image with a round button and transparent
square background, using the GenBitmapButton i still see the square
background as a shade of white. I am not sure if in the conversion
from a wx.Image to a wx.Bitmap i lose the alpha channel or if the
class draws a button in the background and puts the bitmap on it and
that is why i see a square button underneath my round button.

It is a widget. A widget is rectangular. A widget has a background. The
widget's parent's paint is clipped to exclude the child widgets, IOW
that portion of the parent is not even being drawn under normal
circumstances (and leads to flicker if you force it.) These are pretty
much inescapable facts of life in wx.

If you want a non-rectangular thing in which the parent's content shows
through then you either have to fake it by redrawing that portion of the
parent's content on the background of the child, or you need to not use
a child widget at all and instead draw something that looks like a
button directly on the parent and make the parent able to handle the
mouse and keyboard events for it, and send events in response.

Thanks Robin, that clears it up for me. So you are saying that if i
need anything non rectangular i need to use the wx.StaticBitmap as
suggested by others and make the bindings myself.

No, wx.StaticBitmap is a widget too, and so it will have the same issues. Instead you should be handling the paint event for the panel that you normally would have been putting the button upon and drawing the button's bitmap and whatever other widget-like content or other background stuff you want to appear there. You'll probably also want to handle doing things like highlighting the faux-button when the mouse moves over it, and drawing it in a depressed or similar state when the button is pressed, etc. Things like that will make the user more comfortable with your UI and better able to get how it works.

The background of a button widget cannot be made transparent? like the
wx.TANSPARENT_WINDOW?

All that style means is that the window will not get paint events, and is almost useless for anything reasonable since if it doesn't get paint events then it will most likely not be drawn at all, (foreground or background.)

···

On 5/1/12 6:33 PM, VC wrote:

On May 1, 7:56 pm, Robin Dunn<ro...@alldunn.com> wrote:

On 5/1/12 4:38 PM, VC wrote:

--
Robin Dunn
Software Craftsman

BTW, I'm not sure if it's been mentioned yet but you should take a look at the sample in the demo for the agw.ButtonPanel. It already does a lot of what you are wanting.

···

On 5/1/12 7:05 PM, Robin Dunn wrote:

On 5/1/12 6:33 PM, VC wrote:

Thanks Robin, that clears it up for me. So you are saying that if i
need anything non rectangular i need to use the wx.StaticBitmap as
suggested by others and make the bindings myself.

No, wx.StaticBitmap is a widget too, and so it will have the same
issues. Instead you should be handling the paint event for the panel
that you normally would have been putting the button upon and drawing
the button's bitmap and whatever other widget-like content or other
background stuff you want to appear there. You'll probably also want to
handle doing things like highlighting the faux-button when the mouse
moves over it, and drawing it in a depressed or similar state when the
button is pressed, etc. Things like that will make the user more
comfortable with your UI and better able to get how it works.

--
Robin Dunn
Software Craftsman

Thanks Robin, that clears it up for me. So you are saying that if i
need anything non rectangular i need to use the wx.StaticBitmap as
suggested by others and make the bindings myself.
The background of a button widget cannot be made transparent? like the
wx.TANSPARENT_WINDOW?

Sorry, I was wrong about how ButtonPanel was done, as Robin says it
draws them on.

I'm a little confused, though, about why you would, as he mentioned,
have to draw the image yourself in all cases (maybe platform
differences?). Attached is a script with a not-rectangular shaped
"button" (yes, the widget is rectangular but the image uses
transparency) that you can click on. Is this not what you want?...I
must be missing something.

I forgot to also mention Andrea's other contribution, shapedButton:
http://xoomer.virgilio.it/infinity77/main/ShapedButton.html
(also in demo)

odd_shaped_button.py (3.45 KB)

Thank you. I will try the script you wrote. I will try static bitmap
with transparency and i will try what Robin suggested, drawing the
buttons on the background of the panel and then doing the bindings and
of course having mutliple bitmaps for multiple states of the button.
I would use the EVT_PAINT for that one and bind it to the OnPaint
function of the panel correct?
I will also look at the buttonpanel too.

If i want to make a custom slider (using a bitmap for the slider
button), is there a way to have that with the current slider class or
do i have to write my own. In that case can i just override the
OnPaint function of a generic slider or do i need to rewrite another
class?

Thank you
VC

···

On May 1, 11:01 pm, C M <cmpyt...@gmail.com> wrote:

> Thanks Robin, that clears it up for me. So you are saying that if i
> need anything non rectangular i need to use the wx.StaticBitmap as
> suggested by others and make the bindings myself.
> The background of a button widget cannot be made transparent? like the
> wx.TANSPARENT_WINDOW?

Sorry, I was wrong about how ButtonPanel was done, as Robin says it
draws them on.

I'm a little confused, though, about why you would, as he mentioned,
have to draw the image yourself in all cases (maybe platform
differences?). Attached is a script with a not-rectangular shaped
"button" (yes, the widget is rectangular but the image uses
transparency) that you can click on. Is this not what you want?...I
must be missing something.

I forgot to also mention Andrea's other contribution, shapedButton:http://xoomer.virgilio.it/infinity77/main/ShapedButton.html
(also in demo)

odd_shaped_button.py
4KViewDownload

I have looked at shapedbutton, i think it was mainly done to have a
bitmap drawn on a round button, when i try to have my bitmap be the
whole button, i still get a grey rim around the bitmap, as if the
native round button drawn in the background is not completely covered
by the bitmap. I can make that disappear by altering the size of the
button, but there is no one alteration that fits all bitmaps. So for
different sized round buttons the alteration in the size is different.
I want a more generic solution.

Thank you

VC

···

On May 1, 11:01 pm, C M <cmpyt...@gmail.com> wrote:

I forgot to also mention Andrea's other contribution, shapedButton:http://xoomer.virgilio.it/infinity77/main/ShapedButton.html
(also in demo)

If you need a limited number of buttons you could possibly use shaped
windows and catch the on click methods, these would be top level windows
so you might have to reposition them when your application is moved, etc.

Gadget/Steve

···

On 02/05/2012 3:24 PM, VC wrote:

On May 1, 11:01 pm, C M <cmpyt...@gmail.com> wrote:

I forgot to also mention Andrea's other contribution, shapedButton:http://xoomer.virgilio.it/infinity77/main/ShapedButton.html
(also in demo)

I have looked at shapedbutton, i think it was mainly done to have a
bitmap drawn on a round button, when i try to have my bitmap be the
whole button, i still get a grey rim around the bitmap, as if the
native round button drawn in the background is not completely covered
by the bitmap. I can make that disappear by altering the size of the
button, but there is no one alteration that fits all bitmaps. So for
different sized round buttons the alteration in the size is different.
I want a more generic solution.

Thank you

VC

Try doing it with something on the background of the parent other than a solid color. The child widgets will usually inherit the parent's background if it is a solid color that is set before the child is created, so that helps them appear to be transparent because they have the same background color. But if there is a gradient or a bitmap tiled on the background then that doesn't work so well.

···

On 5/1/12 9:01 PM, C M wrote:

Thanks Robin, that clears it up for me. So you are saying that if i
need anything non rectangular i need to use the wx.StaticBitmap as
suggested by others and make the bindings myself.
The background of a button widget cannot be made transparent? like the
wx.TANSPARENT_WINDOW?

Sorry, I was wrong about how ButtonPanel was done, as Robin says it
draws them on.

I'm a little confused, though, about why you would, as he mentioned,
have to draw the image yourself in all cases (maybe platform
differences?). Attached is a script with a not-rectangular shaped
"button" (yes, the widget is rectangular but the image uses
transparency) that you can click on. Is this not what you want?...I
must be missing something.

--
Robin Dunn
Software Craftsman

Thanks Robin, that clears it up for me. So you are saying that if i
need anything non rectangular i need to use the wx.StaticBitmap as
suggested by others and make the bindings myself.
The background of a button widget cannot be made transparent? like the
wx.TANSPARENT_WINDOW?

Sorry, I was wrong about how ButtonPanel was done, as Robin says it
draws them on.

I'm a little confused, though, about why you would, as he mentioned,
have to draw the image yourself in all cases (maybe platform
differences?). Attached is a script with a not-rectangular shaped
"button" (yes, the widget is rectangular but the image uses
transparency) that you can click on. Is this not what you want?...I
must be missing something.

I forgot to also mention Andrea's other contribution, shapedButton:http://xoomer.virgilio.it/infinity77/main/ShapedButton.html
(also in demo)

  odd_shaped_button.py
4KViewDownload

Thank you. I will try the script you wrote. I will try static bitmap
with transparency and i will try what Robin suggested, drawing the
buttons on the background of the panel and then doing the bindings and
of course having mutliple bitmaps for multiple states of the button.
I would use the EVT_PAINT for that one and bind it to the OnPaint
function of the panel correct?

Yes.

I will also look at the buttonpanel too.

If i want to make a custom slider (using a bitmap for the slider
button), is there a way to have that with the current slider class or
do i have to write my own. In that case can i just override the
OnPaint function of a generic slider or do i need to rewrite another
class?

No the look of the native widget is not overridable, you would have to create a custom widget.

···

On 5/2/12 7:21 AM, VC wrote:

On May 1, 11:01 pm, C M<cmpyt...@gmail.com> wrote:

--
Robin Dunn
Software Craftsman

Hi,

No the look of the native widget is not overridable, you would have to
create a custom widget.

Wasn't able to follow all of this thread but sounds like you just want
a bitmap as a button with a transparent background.

Can try looking at wx.lib.platebtn. It goes to great lengths to
achieve a transparent background on whatever its parent widget is.
There are some limitations on GTK where it is not possible, but it can
be done on both windows and OSX.

See the wxPython demo for some samples.

Cody

···

On Wed, May 2, 2012 at 1:33 PM, Robin Dunn <robin@alldunn.com> wrote:

On 5/2/12 7:21 AM, VC wrote:

Try doing it with something on the background of the parent other than a
solid color. The child widgets will usually inherit the parent's background
if it is a solid color that is set before the child is created, so that
helps them appear to be transparent because they have the same background
color. But if there is a gradient or a bitmap tiled on the background then
that doesn't work so well.

D'oh, of course. I have been cheating it with "nearly" matching to
that part of the gradient for a long while and putting off creating
custom widgets someday to get perfect matching and forgot about that
and that the OP might want a non-uniform background. Thanks for the
reminder.

Yup, i tried static bitmap, it has the same square background as a
GenBitmapButton :frowning:

VC

···

On May 2, 3:26 pm, C M <cmpyt...@gmail.com> wrote:

> Try doing it with something on the background of the parent other than a
> solid color. The child widgets will usually inherit the parent's background
> if it is a solid color that is set before the child is created, so that
> helps them appear to be transparent because they have the same background
> color. But if there is a gradient or a bitmap tiled on the background then
> that doesn't work so well.

D'oh, of course. I have been cheating it with "nearly" matching to
that part of the gradient for a long while and putting off creating
custom widgets someday to get perfect matching and forgot about that
and that the OP might want a non-uniform background. Thanks for the
reminder.

Instead you should be handling the paint event for the panel

that you normally would have been putting the button upon and drawing
the button's bitmap and whatever other widget-like content or other
background stuff you want to appear there. You'll probably also want to
handle doing things like highlighting the faux-button when the mouse
moves over it, and drawing it in a depressed or similar state when the
button is pressed, etc. Things like that will make the user more
comfortable with your UI and better able to get how it works.

Robin Dunn
Software Craftsmanhttp://wxPython.org

Ok i made a test panel and drew in the paint event a bunch of bitmaps
for buttons, they render well and look like i want them to. So this is
great.
How However can i capture when the mouse is over the bitmap? Or have
it adjust size and position as the panel is resized?
I am completely lost in this arena. I have acquired some skills using
native buttons and widgets... but not sure where to start to make my
own thing.
Sorry for the amateurism, i only recently started learning this
beautiful library, any help will be appreciated.

VC

Please correct me if i am wrong:

To resize the button when the parent is resized:

I should resize the button in the OnResize function?
i can scale the wx.Image to the new size
And then the OnPaint function will be redrawing it with the new size?

Once I draw the bitmap on the panel that i want to use as a button,
how can i define it or make it as a widget so i can get all the other
functionalities like putting it in a sizer, assigning events to it
etc...
Or do i have to write all that manually like capturing mouse movements
and testing to see if mouse coordinates are within bitmap coordinates
to determine if the bitmap has focus etc...

Thank you
VC

Hi,

Please correct me if i am wrong:

To resize the button when the parent is resized:

I should resize the button in the OnResize function?
i can scale the wx.Image to the new size
And then the OnPaint function will be redrawing it with the new size?

That's a possibility, yes. However, see below.

Once I draw the bitmap on the panel that i want to use as a button,
how can i define it or make it as a widget so i can get all the other
functionalities like putting it in a sizer, assigning events to it
etc...
Or do i have to write all that manually like capturing mouse movements
and testing to see if mouse coordinates are within bitmap coordinates
to determine if the bitmap has focus etc...

If you want it to behave like a widget, it may get complicated
(depending on how complicated the image shape is). However, you could
simply draw your bitmap in a sub-panel, and put that sub-panel into
sizers, i.e.:

class MySubPanel(wx.Panel):

    def __init__(self, parent):

        wx.Panel.__init__(self, parent, style=wx.NO_BORDER)

        # Draw your image in this handler
        self.Bind(wx.EVT_PAINT, self.OnPaint)

        # Handle the image scaling in this handler
        self.Bind(wx.EVT_SIZE, self.OnSize)

For the mouse interaction, I am afraid you will have to code and
implement event handlers for wx.EVT_LEFT_DOWN, wx.EVT_LEFT_UP,
wx.EVT_MOTION (wx.EVT_LEFT_DCLICK on Windows) and possibly
wx.EVT_MOUSE_CAPTURE_LOST. If the image shape is relatively simple,
you may find a way to approximate it using wx.Region and then allowing
mouse-clicks/mouse-overs only when the mouse position is inside that
region.

Andrea.

"Imagination Is The Only Weapon In The War Against Reality."
http://xoomer.alice.it/infinity77/

···

On 3 May 2012 15:33, VC wrote: