5 votes

WxPython changer la forme du bouton bitmap

Bonjour, je suis encore un peu nouveau sur wxPython et encore en train d'apprendre. J'essaie de créer un bouton bitmap en utilisant une image particulière comme ceci par exemple : http://i.min.us/idk3Uy.png

Le truc, c'est que je veux conserver la forme originale de l'image dans le bouton, comme un bouton circulaire par exemple au lieu d'un rectangle (qui est la forme par défaut).

Je veux savoir comment faire exactement ou si c'est possible de le faire du tout ; j'ai jeté un coup d'œil à la documentation et j'ai trouvé que la constante de style wx.BU_EXACTFIT supprime les bordures inutiles... mais ce n'est toujours pas dans la forme souhaitée que je veux qu'elle soit.

Merci.

16voto

FogleBird Points 23405

Vous allez probablement devoir implémenter un contrôle personnalisé pour cela. J'ai déjà réalisé ma part de contrôles personnalisés avec wxPython, donc j'ai écrit une classe ShapedButton pour vous. =)

Pour exécuter cette démo, vous avez juste besoin de trois images :

  • button-normal.png
  • button-pressed.png
  • button-disabled.png

Les trois images sont utilisées en fonction de l'état du bouton. Seule l'image "normal" est requise, mais vous voulez probablement fournir au moins "normal" et "pressed" pour que l'utilisateur obtienne un retour visuel lors du clic.

Le contrôle répond uniquement aux clics dans les zones non transparentes de l'image normale. Il déclenche correctement l'événement EVT_BUTTON lorsqu'il est cliqué et relâché.

Profitez-en!

Capture d'écran de démonstration

import wx

class ShapedButton(wx.PyControl):
    def __init__(self, parent, normal, pressed=None, disabled=None):
        super(ShapedButton, self).__init__(parent, -1, style=wx.BORDER_NONE)
        self.normal = normal
        self.pressed = pressed
        self.disabled = disabled
        self.region = wx.RegionFromBitmapColour(normal, wx.Color(0, 0, 0, 0))
        self._clicked = False
        self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
        self.Bind(wx.EVT_SIZE, self.on_size)
        self.Bind(wx.EVT_PAINT, self.on_paint)
        self.Bind(wx.EVT_LEFT_DOWN, self.on_left_down)
        self.Bind(wx.EVT_LEFT_DCLICK, self.on_left_dclick)
        self.Bind(wx.EVT_LEFT_UP, self.on_left_up)
        self.Bind(wx.EVT_MOTION, self.on_motion)
        self.Bind(wx.EVT_LEAVE_WINDOW, self.on_leave_window)
    def DoGetBestSize(self):
        return self.normal.GetSize()
    def Enable(self, *args, **kwargs):
        super(ShapedButton, self).Enable(*args, **kwargs)
        self.Refresh()
    def Disable(self, *args, **kwargs):
        super(ShapedButton, self).Disable(*args, **kwargs)
        self.Refresh()
    def post_event(self):
        event = wx.CommandEvent()
        event.SetEventObject(self)
        event.SetEventType(wx.EVT_BUTTON.typeId)
        wx.PostEvent(self, event)
    def on_size(self, event):
        event.Skip()
        self.Refresh()
    def on_paint(self, event):
        dc = wx.AutoBufferedPaintDC(self)
        dc.SetBackground(wx.Brush(self.GetParent().GetBackgroundColour()))
        dc.Clear()
        bitmap = self.normal
        if self.clicked:
            bitmap = self.pressed or bitmap
        if not self.IsEnabled():
            bitmap = self.disabled or bitmap
        dc.DrawBitmap(bitmap, 0, 0)
    def set_clicked(self, clicked):
        if clicked != self._clicked:
            self._clicked = clicked
            self.Refresh()
    def get_clicked(self):
        return self._clicked
    clicked = property(get_clicked, set_clicked)
    def on_left_down(self, event):
        x, y = event.GetPosition()
        if self.region.Contains(x, y):
            self.clicked = True
    def on_left_dclick(self, event):
        self.on_left_down(event)
    def on_left_up(self, event):
        if self.clicked:
            x, y = event.GetPosition()
            if self.region.Contains(x, y):
                self.post_event()
        self.clicked = False
    def on_motion(self, event):
        if self.clicked:
            x, y = event.GetPosition()
            if not self.region.Contains(x, y):
                self.clicked = False
    def on_leave_window(self, event):
        self.clicked = False

def main():
    def on_button(event):
        print 'Le bouton a été cliqué.'
    app = wx.PySimpleApp()
    frame = wx.Frame(None, -1, 'Démo du Bouton Forme')
    panel = wx.Panel(frame, -1)
    button = ShapedButton(panel, 
        wx.Bitmap('button-normal.png'), 
        wx.Bitmap('button-pressed.png'), 
        wx.Bitmap('button-disabled.png'))
    button.Bind(wx.EVT_BUTTON, on_button)
    sizer = wx.BoxSizer(wx.VERTICAL)
    sizer.AddStretchSpacer(1)
    sizer.Add(button, 0, wx.ALIGN_CENTER)
    sizer.AddStretchSpacer(1)
    panel.SetSizer(sizer)
    frame.Show()
    app.MainLoop()

if __name__ == '__main__':
    main()

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X