wxPython的 - 借鉴透明/阿尔法的背景(自定义部件/板) [英] wxPython - drawing on transparent/alpha background (for custom widgets/panels)

查看:1183
本文介绍了wxPython的 - 借鉴透明/阿尔法的背景(自定义部件/板)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在Ubuntu Linux学习wxPython的 - 我想定义自己的小部件,它基本上是一条线,我想在窗口移动..我取得了一些进展,但问题是我不能让'部件'在一个透明的背景'画';尽我所能得到的是像这样(的黄线应该是一个独立的小部件具有透明背景 - 但背景有黑色噪音的):

我想出了code如下。我不想整个窗口透明(的wxPython - Python的屏幕上绘制 - 堆栈溢出) ;我知道wx.TRANSPARENT仅适用于文本,我应该尝试wx.GCDC,我做到了,但它不工作(的 wx.PaintDC和SetBackgroundMode(wx.TRANSPARENT)的支持 - wxPython的用户|谷歌论坛),显然,这一点,wxGTK是不可能的(<一href=\"http://wxpython-users.1045709.n5.nabble.com/transparent-background-for-a-panel-widget-td2362723.html\"相对=nofollow> wxPython的用户 - 对于面板部件透明背景)...

看来唯一的办法是使用透明位图/图像,然后使用它作为背景自定义窗口小部件,那会是正确的?如果是这样,有没有产生该位图/图像直接在wxPython中(我的目标一个自包含的脚本,我讨厌使其依赖于外部巴纽:)可能性的)?如果这是一个可行的方法,可以有人点我到最低工作示例(,因为我找不到这种使用任何的例子在所有的)..

在此先感谢您的帮助,结果
干杯!

这上面产生图像code:

 #!的/ usr / bin中/蟒蛇
# - * - 编码:UTF-8 - * - 进口WX类CustomLine(wx.Panel):#PyControl
    
    对于A线自​​定义类
    从http://wiki.wxpython.org/CreatingCustomControls修改
    
    高清__init __(自我,父母,ID = wx.ID_ANY,标签=,POS = wx.DefaultPosition,
            大小= wx.DefaultSize,风格= wx.NO_BORDER,验证= wx.DefaultValidator,
            NAME =CustomLine):
        
        默认的类构造函数。        @param父:父窗口。切不可无。
        @param ID:CustomLine标识符。值-1表示默认值。
        @param标签:显示文本旁边的复选框。
        @param POS:CustomLine位置。如果位置(-1,-1)被指定
                    那么默认的位置被选中。
        @参数尺寸:CustomLine大小。如果默认大小(-1,-1)被指定
                     然后默认大小选择。
        @参数风格:在本演示中没有使用,CustomLine只有2状态
        @参数验证:验证窗口。
        @参数名称:窗口名称。
        
        #〜wx.PyControl .__的init __(自我,父母,编号,POS,大小,样式,验证,名称)
        wx.Panel .__的init __(自我,父母,编号,POS,大小,样式)        #绑定关系到我们控制的事件:首先,我们使用
        wx.BufferedPaintDC的号组合和一个空的处理程序
        #wx.EVT_ERASE_BACKGROUND(见下文),以减少闪烁
        self.Bind(wx.EVT_PAINT,self.OnPaint)
        self.Bind(wx.EVT_ERASE_BACKGROUND,self.OnEraseBackground)
        self.lpen = wx.Pen('黄色',2,wx.SOLID)
        self.imagebkg = wx.EmptyImage(10,10)
        #〜self.imagebkg.SetData((255,255,255))
        #〜self.imagebkg.SetAlphaData(1)    高清的OnPaint(个体经营,事件):
        句柄CustomLine的wx.EVT_PAINT事件        #如果你想减少闪烁,一个良好的出发点是
        #使用wx.BufferedPaintDC。
        PDC = wx.BufferedPaintDC(个体经营)
        DC = wx.GCDC(PDC)        #是建议您不要过度拥挤OnPaint事件
        #(或任何其他事件)有很多code,所以让我们做的
        在Draw()方法#实际绘制,传递新
        #初始化wx.BufferedPaintDC
        self.Draw(DC)    高清画(个​​体经营,DC):
        
        实际执行绘图操作,位图和
        文本,定位它们垂直居中。
                #获取自己的实际客户端大小
        宽度,高度= self.GetClientSize()        如果没有宽度或高度不:
            #没事做,我们还没有尺寸!
            返回        #初始化wx.BufferedPaintDC,分配背景
        #颜色和前景色(绘制文本)
        #〜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)    高清OnEraseBackground(个体经营,事件):
        句柄CustomLine的wx.EVT_ERASE_BACKGROUND事件        #这是故意空的,因为我们使用的是组合
        wx.BufferedPaintDC的#+空OnEraseBackground事件
        #减少闪烁
        通过类MyTestFrame(wx.Frame):
    高清__init __(自我,父母,标题):
        超(MyTestFrame,个体经营).__的init __(父母,标题=标题,
            大小=(250,150))        #帧的主面板 - 添加面板,所以它看起来在所有平台上正确
        self.panel = wx.Panel(个体经营,wx.ID_ANY)
            #self.panel.SetBackgroundColour(wx.Colour(124,224,124))#确认广场是面板        self.mpanelA = wx.Panel(self.panel,-1,大小=(200,50))
        self.mpanelA.SetBackgroundColour((200100200))
        self.mpanelB = wx.Panel(self.panel,-1,大小=(50200),POS =(50,30))
        self.mpanelB.SetBackgroundColour(wx.Colour(200100100100))        self.cline = CustomLine(self.panel,-1,大小=( - 1200))        self.Centre()
        self.Show()
如果__name__ =='__main__':
    应用= wx.App()
    MyTestFrame(无,测试)
    app.MainLoop()


解决方案

也许你应该看看直流GraphicsContext istead(的DrawingContext)。它具有透明度更好的支持,就像在面板绘制矩形透明

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.

这篇关于wxPython的 - 借鉴透明/阿尔法的背景(自定义部件/板)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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