2011-06-23 78 views
4

嗨,我對wxPython進行了全新的修改,但仍處於學習過程中。我試圖做一個使用這樣的特定圖像的位圖按鈕,例如:http://i.min.us/idk3Uy.pngWxPython更改位圖按鈕的形狀

捕捉是我想保留按鈕中的圖像的原始形狀,例如圓形按鈕,而不是矩形一個(默認)。

我想知道如何做到這一點,或者如果有可能做到這一點;我查看了文檔,發現它的樣式常量wx.BU_EXACTFIT刪除了不必要的邊框......但它仍然不符合我希望的形狀。

謝謝。

回答

15

您可能將不得不爲此實現自定義控件。我已經完成了我自定義的wxPython控件,所以我繼續爲你寫了一個ShapedButton類。 =)

要運行這個演示,你只需要三個圖像:

  • 按鈕normal.png
  • 按鈕pressed.png
  • 按鈕disabled.png

根據按鈕的狀態使用三個圖像。只需要「正常」的,但您可能希望至少提供「正常」和「按下」,以便用戶在點擊時獲得反饋。

該控件僅響應正常位圖的不透明區域中的點擊。點擊並釋放後,它會正確觸發EVT_BUTTON事件。

享受!

Demo Screenshot

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() 
+0

我不能說我的感激之情是你的,我連問的IRC @Freenode上#wxpython,並沒有得到任何迴應...您的代碼似乎很好地工作我不得不仔細看看它。最初,當我在Windows上運行我的代碼時,該按鈕顯然是圓形的,但是在Linux上它似乎有一個矩形的形狀,在嘗試完代碼後,問題似乎已經解決。非常感謝! –