Python 如何创建具有可见边框的透明边框?

Python 如何创建具有可见边框的透明边框?,python,wxpython,Python,Wxpython,我想创建一个具有可见边框的透明框架。我根据hasenj的“成形框架”(shapedframe)的工作编写的代码如下。但我在做一个还是有问题。我一定错过了什么。有人能指出这个程序有什么问题吗?谢谢 在主循环之外绘制东西不是个好主意。您应该将wx应用程序设置为事件驱动。应处理事件EVT_PAINT和EVT_SIZE。wx.Timer可用于基本移动 import wx #================================================================

我想创建一个具有可见边框的透明框架。我根据hasenj的“成形框架”(shapedframe)的工作编写的代码如下。但我在做一个还是有问题。我一定错过了什么。有人能指出这个程序有什么问题吗?谢谢




在主循环之外绘制东西不是个好主意。您应该将wx应用程序设置为事件驱动。应处理事件EVT_PAINT和EVT_SIZE。
wx.Timer
可用于基本移动

import wx

#============================================================================= 
class DrawPanelDB(wx.Panel):
    def __init__(self, *args, **kwargs):
        wx.Panel.__init__(self, *args, **kwargs)

        self.ballPosition = [20, 20]
        self.ballDelta = [1, 1]

        self.timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.OnTime, self.timer)
        self.timer.Start(20)

        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.Bind(wx.EVT_SIZE, self.OnSize)
        self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)

    #-------------------------------------------------------------------------
    def OnPaint(self, event):
        dc = wx.BufferedPaintDC(self)
        dc.SetBackground(wx.Brush(wx.BLACK))
        dc.Clear()
        dc.DrawCirclePoint(self.ballPosition, 20)

    #-------------------------------------------------------------------------
    def OnSize(self, event):
        self.Refresh()
        self.Update()

    #-------------------------------------------------------------------------
    def OnEraseBackground(self, event):
        pass # Or None  

    #-------------------------------------------------------------------------
    def OnTime(self, event):
        self.ballPosition[0] += self.ballDelta[0]
        self.ballPosition[1] += self.ballDelta[1]
        w, h = self.GetClientSizeTuple()
        if self.ballPosition[0] > w:
            self.ballPosition[0] = w
            self.ballDelta[0] *= -1
        if self.ballPosition[1] > h:
            self.ballPosition[1] = h
            self.ballDelta[1] *= -1
        if self.ballPosition[0] < 0:
            self.ballPosition[0] = 0
            self.ballDelta[0] *= -1
        if self.ballPosition[1] < 0:
            self.ballPosition[1] = 0
            self.ballDelta[1] *= -1       
        self.Refresh()

#============================================================================= 
class MainWindow(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)
        self.panel = DrawPanelDB(self)
        self.Show()

#============================================================================= 
app = wx.App(False)
win = MainWindow(None)
app.MainLoop()
导入wx
#============================================================================= 
类DrawPanelDB(wx.Panel):
定义初始化(self,*args,**kwargs):
wx.Panel.\uuuuu init\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
self.ballPosition=[20,20]
self.ballDelta=[1,1]
self.timer=wx.timer(self)
self.Bind(wx.EVT_TIMER、self.OnTime、self.TIMER)
自动定时器启动(20)
self.Bind(wx.EVT_-PAINT,self.OnPaint)
self.Bind(wx.EVT_大小,self.OnSize)
self.Bind(wx.EVT_ERASE_BACKGROUND,self.OnEraseBackground)
#-------------------------------------------------------------------------
def OnPaint(自身、事件):
dc=wx.BufferedPaintDC(自)
直流立根接地(wx电刷(wx黑色))
dc.Clear()
直流牵引回路点(自球位置,20)
#-------------------------------------------------------------------------
def OnSize(自身、事件):
self.Refresh()
self.Update()
#-------------------------------------------------------------------------
def OnEraseBackground(自身、事件):
通过或不通过
#-------------------------------------------------------------------------
def OnTime(自我、事件):
self.ballPosition[0]+=self.ballDelta[0]
self.ballPosition[1]+=self.ballDelta[1]
w、 h=self.GetClientSizeTuple()
如果自球位置[0]>w:
自球位置[0]=w
self.ballDelta[0]*=-1
如果自球位置[1]>h:
自球位置[1]=h
self.ballDelta[1]*=-1
如果自球位置[0]<0:
自身球位[0]=0
self.ballDelta[0]*=-1
如果自球位置[1]<0:
自身球位[1]=0
self.ballDelta[1]*=-1
self.Refresh()
#============================================================================= 
类主窗口(wx.Frame):
定义初始化(self,*args,**kwargs):
wx.Frame.\uuuuu初始化(self,*args,**kwargs)
self.panel=DrawPanelDB(self)
self.Show()
#============================================================================= 
app=wx.app(假)
win=主窗口(无)
app.MainLoop()

编辑:ScreenDC使用xor函数进行非破坏性绘图的示例

import wx

#============================================================================= 
class MainWindow(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)

        self.ballPosition = [20, 20]
        self.lastPosition = None
        self.ballDelta = [1, 1]

        self.timer = wx.Timer(self)        
        self.Bind(wx.EVT_TIMER, self.OnTime, self.timer)
        self.timer.Start(20)

    #-------------------------------------------------------------------------
    def OnTime(self, event):
        self.ballPosition[0] += self.ballDelta[0]
        self.ballPosition[1] += self.ballDelta[1]
        w, h = wx.DisplaySize()
        if self.ballPosition[0] > w:
            self.ballPosition[0] = w
            self.ballDelta[0] *= -1
        if self.ballPosition[1] > h:
            self.ballPosition[1] = h
            self.ballDelta[1] *= -1
        if self.ballPosition[0] < 0:
            self.ballPosition[0] = 0
            self.ballDelta[0] *= -1
        if self.ballPosition[1] < 0:
            self.ballPosition[1] = 0
            self.ballDelta[1] *= -1       

        dc = wx.ScreenDC()
        dc.StartDrawingOnTop()
        dc.SetLogicalFunction(wx.XOR) 
        if self.lastPosition is not None:
            dc.DrawRectangle(self.lastPosition[0], self.lastPosition[1], 15, 15)
        self.lastPosition = (self.ballPosition[0], self.ballPosition[1])
        dc.DrawRectangle(self.ballPosition[0], self.ballPosition[1], 15, 15)    
        dc.EndDrawingOnTop()

#============================================================================= 
app = wx.App(False)
win = MainWindow(None)
app.MainLoop()
导入wx
#============================================================================= 
类主窗口(wx.Frame):
定义初始化(self,*args,**kwargs):
wx.Frame.\uuuuu初始化(self,*args,**kwargs)
self.ballPosition=[20,20]
self.lastPosition=None
self.ballDelta=[1,1]
self.timer=wx.timer(self)
self.Bind(wx.EVT_TIMER、self.OnTime、self.TIMER)
自动定时器启动(20)
#-------------------------------------------------------------------------
def OnTime(自我、事件):
self.ballPosition[0]+=self.ballDelta[0]
self.ballPosition[1]+=self.ballDelta[1]
w、 h=wx.DisplaySize()
如果自球位置[0]>w:
自球位置[0]=w
self.ballDelta[0]*=-1
如果自球位置[1]>h:
自球位置[1]=h
self.ballDelta[1]*=-1
如果自球位置[0]<0:
自身球位[0]=0
self.ballDelta[0]*=-1
如果自球位置[1]<0:
自身球位[1]=0
self.ballDelta[1]*=-1
dc=wx.ScreenDC()
dc.StartDrawingOnTop()
dc.SetLogicalFunction(wx.XOR)
如果self.lastPosition不是None:
dc.DrawRectangle(self.lastPosition[0],self.lastPosition[1],15,15)
self.lastPosition=(self.ballPosition[0],self.ballPosition[1])
dc.DrawRectangle(自球位置[0],自球位置[1],15,15)
dc.EndDrawingOnTop()
#============================================================================= 
app=wx.app(假)
win=主窗口(无)
app.MainLoop()

编辑:另一种可能是保留屏幕该部分的备份副本

import wx

#============================================================================= 
class MainWindow(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)

        self.ballPosition = [20, 20]
        self.lastPosition = None
        self.ballDelta = [1, 1]
        self.patch = wx.EmptyBitmap(20, 20)

        self.timer = wx.Timer(self)        
        self.Bind(wx.EVT_TIMER, self.OnTime, self.timer)
        self.timer.Start(20)

    #-------------------------------------------------------------------------
    def OnTime(self, event):
        self.ballPosition[0] += self.ballDelta[0]
        self.ballPosition[1] += self.ballDelta[1]
        w, h = wx.DisplaySize()
        if self.ballPosition[0] > w:
            self.ballPosition[0] = w
            self.ballDelta[0] *= -1
        if self.ballPosition[1] > h:
            self.ballPosition[1] = h
            self.ballDelta[1] *= -1
        if self.ballPosition[0] < 0:
            self.ballPosition[0] = 0
            self.ballDelta[0] *= -1
        if self.ballPosition[1] < 0:
            self.ballPosition[1] = 0
            self.ballDelta[1] *= -1       

        dc = wx.ScreenDC()
        dc.StartDrawingOnTop()

        bdc = wx.MemoryDC(self.patch)
        if self.lastPosition is not None:
            dc.Blit(self.lastPosition[0] - 2, self.lastPosition[1] - 2, 20, 20, bdc, 0, 0)
        bdc.Blit(0, 0, 20, 20, dc, self.ballPosition[0] - 2, self.ballPosition[1] - 2)
        self.lastPosition = (self.ballPosition[0], self.ballPosition[1])

        dc.DrawRectangle(self.ballPosition[0], self.ballPosition[1], 15, 15)    
        dc.EndDrawingOnTop()

#============================================================================= 
app = wx.App(False)
win = MainWindow(None)
app.MainLoop()
导入wx
#============================================================================= 
类主窗口(wx.Frame):
定义初始化(self,*args,**kwargs):
wx.Frame.\uuuuu初始化(self,*args,**kwargs)
self.ballPosition=[20,20]
self.lastPosition=None
self.ballDelta=[1,1]
self.patch=wx.EmptyBitmap(20,20)
self.timer=wx.timer(self)
self.Bind(wx.EVT_TIMER、self.OnTime、self.TIMER)
自动定时器启动(20)
#-------------------------------------------------------------------------
def OnTime(自我、事件):
self.ballPosition[0]+=self.ballDelta[0]
self.ballPosition[1]+=self.ballDelta[1]
w、 h=wx.DisplaySize()
如果自球位置[0]>w:
自球位置[0]=w
self.ballDelta[0]*=-1
如果自球位置[1]>h:
自球位置[1]=h
self.ballDelta[1]*=-1
如果自球位置[0]<0:
自身球位[0]=0
self.ballDelta[0]*=-1
如果自球位置[1]<0:
自身球位[1]=0
self.ballDelta[1]*=-1
dc=wx.ScreenDC()
dc.StartDrawingOnTop()
bdc=wx.MemoryDC(self.patch)
import wx

#============================================================================= 
class MainWindow(wx.Frame):
    def __init__(self, *args, **kwargs):
        wx.Frame.__init__(self, *args, **kwargs)

        self.ballPosition = [20, 20]
        self.lastPosition = None
        self.ballDelta = [1, 1]
        self.patch = wx.EmptyBitmap(20, 20)

        self.timer = wx.Timer(self)        
        self.Bind(wx.EVT_TIMER, self.OnTime, self.timer)
        self.timer.Start(20)

    #-------------------------------------------------------------------------
    def OnTime(self, event):
        self.ballPosition[0] += self.ballDelta[0]
        self.ballPosition[1] += self.ballDelta[1]
        w, h = wx.DisplaySize()
        if self.ballPosition[0] > w:
            self.ballPosition[0] = w
            self.ballDelta[0] *= -1
        if self.ballPosition[1] > h:
            self.ballPosition[1] = h
            self.ballDelta[1] *= -1
        if self.ballPosition[0] < 0:
            self.ballPosition[0] = 0
            self.ballDelta[0] *= -1
        if self.ballPosition[1] < 0:
            self.ballPosition[1] = 0
            self.ballDelta[1] *= -1       

        dc = wx.ScreenDC()
        dc.StartDrawingOnTop()

        bdc = wx.MemoryDC(self.patch)
        if self.lastPosition is not None:
            dc.Blit(self.lastPosition[0] - 2, self.lastPosition[1] - 2, 20, 20, bdc, 0, 0)
        bdc.Blit(0, 0, 20, 20, dc, self.ballPosition[0] - 2, self.ballPosition[1] - 2)
        self.lastPosition = (self.ballPosition[0], self.ballPosition[1])

        dc.DrawRectangle(self.ballPosition[0], self.ballPosition[1], 15, 15)    
        dc.EndDrawingOnTop()

#============================================================================= 
app = wx.App(False)
win = MainWindow(None)
app.MainLoop()