2011-03-01 28 views
2

我在Ubuntu Linux上學習wxPython - 我想定義我自己的小部件,它基本上是一條線,我想移動圍繞窗口..我取得了一些進展,但問題是,我不能讓「部件」,以在透明背景上「畫」;盡我所能得到的是這樣的事情(黃線應與一個透明背景的獨立部件 - 但背景有黑色與噪音):wxPython - 在透明/ alpha背景上繪圖(用於自定義小部件/面板)

bad transparency in this wxPython example

我想出的代碼下面。我不想整個窗口透明(wxpython - Python drawing on screen - Stack Overflow);我知道wx.TRANSPARENT僅適用於文本,我應該嘗試wx.GCDC,我做到了,但它不工作(wx.PaintDC and SetBackgroundMode(wx.TRANSPARENT) support - wxPython-users | Google Groups),顯然,這一點,「wxGTK這是不可能的」(wxPython-users - transparent background for a panel widget) ...

它似乎唯一的方法是使用透明的位圖/圖像,然後用它作爲自定義小部件的背景,那是正確的嗎?如果是這樣,有產生此位圖/圖像直接在wxPython的可能性(我的目標一個自包含的腳本,我討厭使其依賴於外部巴紐:))?如果這是一個可行的方法,可以有人點我到最低工作示例(,因爲我無法找到這種使用在所有任何實例)..

在此先感謝您的幫助,
乾杯!

#!/usr/bin/python 
# -*- coding: utf-8 -*- 

import wx 

class CustomLine(wx.Panel): #PyControl 
    """ 
    A custom class for a line 
    Modified from http://wiki.wxpython.org/CreatingCustomControls 
    """ 
    def __init__(self, parent, id=wx.ID_ANY, label="", pos=wx.DefaultPosition, 
      size=wx.DefaultSize, style=wx.NO_BORDER, validator=wx.DefaultValidator, 
      name="CustomLine"): 
     """ 
     Default class constructor. 

     @param parent: Parent window. Must not be None. 
     @param id: CustomLine identifier. A value of -1 indicates a default value. 
     @param label: Text to be displayed next to the checkbox. 
     @param pos: CustomLine position. If the position (-1, -1) is specified 
        then a default position is chosen. 
     @param size: CustomLine size. If the default size (-1, -1) is specified 
        then a default size is chosen. 
     @param style: not used in this demo, CustomLine has only 2 state 
     @param validator: Window validator. 
     @param name: Window name. 
     """ 
     #~ wx.PyControl.__init__(self, parent, id, pos, size, style, validator, name) 
     wx.Panel.__init__(self, parent, id, pos, size, style) 

     # Bind the events related to our control: first of all, we use a 
     # combination of wx.BufferedPaintDC and an empty handler for 
     # wx.EVT_ERASE_BACKGROUND (see later) to reduce flicker 
     self.Bind(wx.EVT_PAINT, self.OnPaint) 
     self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground) 
     self.lpen = wx.Pen('yellow', 2, wx.SOLID) 
     self.imagebkg = wx.EmptyImage(10, 10) 
     #~ self.imagebkg.SetData((255,255,255)) 
     #~ self.imagebkg.SetAlphaData((1)) 

    def OnPaint(self, event): 
     """ Handles the wx.EVT_PAINT event for CustomLine. """ 

     # If you want to reduce flicker, a good starting point is to 
     # use wx.BufferedPaintDC. 
     pdc = wx.BufferedPaintDC(self) 
     dc = wx.GCDC(pdc) 

     # Is is advisable that you don't overcrowd the OnPaint event 
     # (or any other event) with a lot of code, so let's do the 
     # actual drawing in the Draw() method, passing the newly 
     # initialized wx.BufferedPaintDC 
     self.Draw(dc) 

    def Draw(self, dc): 
     """ 
     Actually performs the drawing operations, for the bitmap and 
     for the text, positioning them centered vertically. 
     """ 

     # Get the actual client size of ourselves 
     width, height = self.GetClientSize() 

     if not width or not height: 
      # Nothing to do, we still don't have dimensions! 
      return 

     # Initialize the wx.BufferedPaintDC, assigning a background 
     # colour and a foreground colour (to draw the text) 
     #~ backColour = self.GetBackgroundColour() 
     #~ backBrush = wx.Brush((1,1,1,150), wx.TRANSPARENT) # backColour 
     #~ backBrush = wx.Brush((10,10,1,150)) # backColour 
     dc.SetBackground(wx.TRANSPARENT_BRUSH) #() backBrush 
     #~ dc.SetBackgroundMode(wx.TRANSPARENT) 
     dc.Clear() 

     dc.SetPen(self.lpen) 
     dc.DrawLine(0, 0, 100, 100) 

    def OnEraseBackground(self, event): 
     """ Handles the wx.EVT_ERASE_BACKGROUND event for CustomLine. """ 

     # This is intentionally empty, because we are using the combination 
     # of wx.BufferedPaintDC + an empty OnEraseBackground event to 
     # reduce flicker 
     pass 

class MyTestFrame(wx.Frame): 
    def __init__(self, parent, title): 
     super(MyTestFrame, self).__init__(parent, title=title, 
      size=(250, 150)) 

     # the master panel of the frame - "Add a panel so it looks correct on all platforms" 
     self.panel = wx.Panel(self, wx.ID_ANY) 
      # self.panel.SetBackgroundColour(wx.Colour(124, 224, 124)) # to confirm the square is the panel 

     self.mpanelA = wx.Panel(self.panel, -1, size=(200,50)) 
     self.mpanelA.SetBackgroundColour((200,100,200)) 
     self.mpanelB = wx.Panel(self.panel, -1, size=(50,200), pos=(50,30)) 
     self.mpanelB.SetBackgroundColour(wx.Colour(200,100,100,100)) 

     self.cline = CustomLine(self.panel, -1, size=(-1,200)) 

     self.Centre() 
     self.Show() 


if __name__ == '__main__': 
    app = wx.App() 
    MyTestFrame(None, 'Test') 
    app.MainLoop() 

回答

1

也許你應該看看直流GraphicsContext istead(的DrawingContext):產生上述圖像

代碼。它具有透明度更好的支持,就像在面板繪製矩形透明。

+0

真棒,感謝您的@Lars - 將在不久之後進行檢查,並報告;乾杯! – sdaau 2011-11-01 12:30:03