WxPython 改变位图按钮的形状 [英] WxPython changing the shape of bitmap button

查看:41
本文介绍了WxPython 改变位图按钮的形状的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 wxPython 的新手,仍在学习中.我正在尝试使用这样的特定图像制作位图按钮,例如:http://i.min.us/idk3Uy.png

Hi I'm sort new to wxPython and still in the process of learning. I'm trying to make a bitmap button using a particular image like this for example: http://i.min.us/idk3Uy.png

问题是我想保留按钮中图像的原始形状,例如圆形按钮而不是矩形按钮(这是默认设置).

The catch is I want to retain the original shape of the image in the button, like a circular button for example instead of a rectangular one (which is default).

我想知道如何确切地做到这一点,或者是否有可能做到这一点;我确实查看了文档,我发现样式常量 wx.BU_EXACTFIT 删除了不必要的边框......但它仍然不是我想要的理想形状.

I want to know how to do that exactly or if it is possible to do that at all; I did take a look at the documentation and I've found the style constant wx.BU_EXACTFIT removes the unnecessary borders...but it's still not in the desirable shape that I want it to be.

谢谢.

推荐答案

您可能需要为此实现自定义控件.我已经完成了自定义 wxPython 控件的大部分工作,所以我继续为您编写了一个 ShapedButton 类.=)

You're probably going to have to implement a custom control for this. I've done my fair share of custom wxPython controls, so I went ahead and wrote a ShapedButton class for you. =)

要运行此演示,您只需要三个图像:

To run this demo, you just need three images:

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

根据按钮的状态使用三个图像.只需要正常"一个,但您可能希望至少提供正常"和按下",以便用户在点击时获得反馈.

The three images are used depending on the state of the button. Only the "normal" one is required, but you probably want to at least provide "normal" and "pressed" so the user gets feedback when clicking.

该控件仅响应普通位图非透明区域中的点击.单击并释放时,它会正确触发 EVT_BUTTON 事件.

The control only responds to clicks in non-transparent areas of the normal bitmap. It properly fires the EVT_BUTTON event when clicked and released.

享受吧!

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 'Button was clicked.'
    app = wx.PySimpleApp()
    frame = wx.Frame(None, -1, 'Shaped Button Demo')
    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()

这篇关于WxPython 改变位图按钮的形状的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆