views:

404

answers:

5

I'd like to make a custom button in wxPython. Where should I start, how should I do it?

+2  A: 

You can extend the default button class, like this for example:

class RedButton(wx.Button):
    def __init__(self, *a, **k):
        wx.Button.__init__(self, *a, **k)
        self.SetBackgroundColour('RED')
        # more customization here

Every time you put a RedButton into your layout, it should appear red (haven't tested it though).

Otto Allmendinger
A: 

Is there a way to make a completely different-looking button, not using operating system's standard appearance? Maybe disabling the standard rendering of a button in the child class and then making a custom rendering system?

TerabyteST
You can always start from scratch with an empty wxWindow widget and use the GC (graphic context) to draw whatever you want on it, and do whatever you want on mouse events.
Otto Allmendinger
Please just edit your question rather than posting this edit as an answer.
tom10
see my answer - for total custom buttons
Anurag Uniyal
+1  A: 

Try using a Generic Button or a Bitmap Button.

Toni Ruža
+1  A: 

When I wanted to learn how to make custom widgets (buttons included) I referenced Andrea Gavana's page (full working example there) on the wxPyWiki and Cody Precord's platebutton (the source is in wx.lib.platebtn, also here in svn). Look at both of those and you should be able to build most any custom widget you would like.

DrBloodmoney
+1  A: 

Here is a skeleton which you can use to draw totally custom button, its up to your imagination how it looks or behaves

class MyButton(wx.PyControl):

    def __init__(self, parent, id, bmp, text, **kwargs):
        wx.PyControl.__init__(self,parent, id, **kwargs)

        self.Bind(wx.EVT_LEFT_DOWN, self._onMouseDown)
        self.Bind(wx.EVT_LEFT_UP, self._onMouseUp)
        self.Bind(wx.EVT_LEAVE_WINDOW, self._onMouseLeave)
        self.Bind(wx.EVT_ENTER_WINDOW, self._onMouseEnter)
        self.Bind(wx.EVT_ERASE_BACKGROUND,self._onEraseBackground)
        self.Bind(wx.EVT_PAINT,self._onPaint)

        self._mouseIn = self._mouseDown = False

    def _onMouseEnter(self, event):
        self._mouseIn = True

    def _onMouseLeave(self, event):
        self._mouseIn = False

    def _onMouseDown(self, event):
        self._mouseDown = True

    def _onMouseUp(self, event):
        self._mouseDown = False
        self.sendButtonEvent()

    def sendButtonEvent(self):
        event = wx.CommandEvent(wx.wxEVT_COMMAND_BUTTON_CLICKED, self.GetId())
        event.SetInt(0)
        event.SetEventObject(self)
        self.GetEventHandler().ProcessEvent(event)

    def _onEraseBackground(self,event):
        # reduce flicker
        pass

    def _onPaint(self, event):
        dc = wx.BufferedPaintDC(self)
        dc.SetFont(self.GetFont())
        dc.SetBackground(wx.Brush(self.GetBackgroundColour()))
        dc.Clear()
        # draw whatever you want to draw
        # draw glossy bitmaps e.g. dc.DrawBitmap
        if self._mouseIn:
            pass# on mouserover may be draw different bitmap
        if self._mouseDown:
            pass # draw different image text
Anurag Uniyal