在 Windows10 上,如何获得具有透明背景的 wx.Window 以避免移动时出现拖尾?

问题描述

我一直在开发一个程序,有点像在 mac 上使用 wxpython 的绘图程序。它在我的 Mac 上运行良好,我已经开始在 Windows 上进行测试。我现在在 Windows 上运行良好,但重叠 wx.Windows 与透明背景不能正确绘制。我已经整理了一个显示问题的小型演示应用程序。有 3 个窗口,每个窗口绘制一个圆圈,一个红色、一个绿色、一个蓝色,您可以在框架周围拖动它们。

在 Mac 上,这些保持清晰且反应灵敏,而且看起来很漂亮。它们还保留了它们的绘制顺序/z 顺序:底部是红色,然后是绿色,然后是顶部蓝色。

但是在 Windows 上运行时,它们从圆圈边缘周围的奇怪灰色背景开始。然后在拖动时,圆圈周围的灰色角落显示来自其他圆圈的颜色和黑色轮廓的污点。最后,最近拖动的圆圈出现在顶部,而命中测试似乎以相反的顺序工作,让我点击红色的,即使它被其他圆圈覆盖。

所以,首先,我想弄清楚如何让 Shape 窗口的透明背景在 Windows 10 平台上正常工作。然后我可以挖掘其余部分。

感谢您查看此内容。我期待您的任何想法!

版本

  • MacOS 10.15.7、python 3.8、wxPython 4.1.1
  • Windows 10、python 3.9、wxPython 4.1.1

以下是在 Mac 和 Windows 10 上运行的以下测试程序的屏幕截图,在拖动圆圈一段时间后。

On the Mac: note the circles overlapping in the correct order

On Win10: Note the smearing and incorrect draw order

import wx

class Shape(wx.Window):
    def __init__(self,*args,**kwargs):
        self.color = kwargs.pop("color")
        super().__init__()
        self.SetBackgroundStyle(wx.BG_STYLE_TRANSPARENT)
        self.Create(*args,**kwargs)

        self.Bind(wx.EVT_PAINT,self.OnPaint)
        self.Bind(wx.EVT_LEFT_DOWN,self.OnMouseDown)
        self.Bind(wx.EVT_MOTION,self.OnMouseMove)
        self.Bind(wx.EVT_LEFT_UP,self.onmouseup)

    def OnPaint(self,event):
        dc = wx.PaintDC(self)
        dc.SetPen(wx.Pen('black',2,wx.PENSTYLE_SOLID))
        dc.SetBrush(wx.Brush(self.color,wx.BrushSTYLE_SOLID))
        s = self.GetSize()
        dc.DrawEllipse(1,1,s.width-2,s.height-2)  # Inset to allow for pen width

    def OnMouseDown(self,event):
        self.offset = event.GetPosition()
        self.CaptureMouse()

    def OnMouseMove(self,event):
        if self.HasCapture():
            pos = self.GetParent().ScreenToClient(event.GetEventObject().ClientToScreen(event.GetPosition()))
            self.SetPosition((pos.x-self.offset.x,pos.y-self.offset.y))
            self.Refresh(True)

    def onmouseup(self,event):
        self.ReleaseMouse()


class TestFrame(wx.Frame):
    def __init__(self,**kwargs):
        super().__init__(*args,**kwargs)
        self.client = wx.Window(self)
        self.Bind(wx.EVT_SIZE,self.OnSize)
        self.client.SetBackgroundColour('white')
        Shape(self.client,color="red",pos=(20,20),size=(50,50))
        Shape(self.client,color="green",pos=(120,color="blue",pos=(70,100),50))

    def OnSize(self,event):
        self.client.SetSize(self.GetSize())


class TestApp(wx.App):
    def OnInit(self):
        self.frame = TestFrame(None,size=(200,200))
        self.frame.app = self
        self.frame.Show(True)
        self.SetTopWindow(self.frame)
        return True


if __name__ == '__main__':
    app = TestApp(redirect=False)
    app.MainLoop()

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)