wxpython bind自定义_wxPython的 - 借鉴透明/阿尔法的背景(自定义部件/板)

I'm learning wxPython on Ubuntu Linux - and I would like to define my own widget, which is basically a line, which I'd like to move around the window.. I'm getting somewhere, but the problem is that I cannot get the 'widget' to 'draw' on a transparent background; best I can get is something like this (the yellow line should be an independent widget with a transparent background - but the background there is black with noise):

The code I came up with is below. I don't want the whole window transparent (wxpython - Python drawing on screen - Stack Overflow); I'm aware wx.TRANSPARENT is only for text, and I should try wx.GCDC, which I did, but it isn't working (wx.PaintDC and SetBackgroundMode( wx.TRANSPARENT ) support - wxPython-users | Google Groups), and apparently, this, on "wxGTK it is not possible" (wxPython-users - transparent background for a panel widget)...

It seems the only way would be to use a transparent bitmap/Image, and then use that as background for a custom widget, would that be correct? If so, is there a possibility to generate this bitmap/image directly in wxPython (I'm aiming for a self-contained script, I'd hate to make it dependent on an external .png :)) ? And if this is a possible approach, can someone point me to a minimal working example (as I cannot find any examples for this kind of use at all)..

Thanks in advance for any help,

Cheers!

code that generated image above:

#!/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()

解决方案

maybe you should have a look at GraphicsContext istead of dc (DrawingContext). It has better support for transparency, like drawing transparent rectangles on to of a panel.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值