【问题标题】:WxPython changing the shape of bitmap buttonWxPython 改变位图按钮的形状
【发布时间】:2011-06-23 05:27:20
【问题描述】:

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

关键是我想在按钮中保留图像的原始形状,例如圆形按钮而不是矩形按钮(这是默认的)。

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

谢谢。

【问题讨论】:

    标签: python wxpython


    【解决方案1】:

    您可能必须为此实现自定义控件。我已经完成了相当多的自定义 wxPython 控件,所以我继续为您编写了一个 ShapedButton 类。 =)

    要运行此演示,您只需要三张图片:

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

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

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

    享受吧!

    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 上的 IRC @Freenode 上问过,但没有得到任何回应......你的代码似乎运行良好,我'我得仔细看看。最初,当我在 Windows 上运行我的代码时,按钮显然是圆形的,但在 Linux 上,在尝试了你的代码后,它似乎有一个矩形形状,问题似乎得到了解决。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2018-07-12
    • 2020-06-13
    • 1970-01-01
    • 1970-01-01
    • 2021-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多