Python在屏幕上绘图

7 投票
1 回答
8122 浏览
提问于 2025-04-15 19:39

我正在编写一个应用程序,需要选择屏幕上的一个区域。我想把鼠标指针改成十字形,然后在用户选择的区域上画一个矩形。我首先查找了如何操作鼠标指针,发现了wxPython。使用wxPython,我可以很容易地在一个框架和面板上实现这个功能,但问题是我需要让窗口透明,这样用户在选择区域时才能看到屏幕。不过,如果我把框架和面板设置成透明,整个程序就会出现问题。

所以,我对任何解决方案都持开放态度,无论是使用wxPython还是不使用,因为我也不太确定自己是不是在正确使用它。

我刚开始学习Python,而且我的英语不是母语,所以如果有些地方你听不懂,我很抱歉。

这是我写的代码

import wx

class SelectableFrame(wx.Frame):

    c1 = None
    c2 = None

    def __init__(self, parent=None, id=-1, title=""):
        wx.Frame.__init__(self, parent, id, title, size=wx.DisplaySize(), style=wx.TRANSPARENT_WINDOW)

        self.panel = wx.Panel(self, size=self.GetSize(), style=wx.TRANSPARENT_WINDOW)

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

        self.SetCursor(wx.StockCursor(wx.CURSOR_CROSS))

    def OnMouseMove(self, event):
        if event.Dragging() and event.LeftIsDown():
            self.c2 = event.GetPosition()
            self.Refresh()

    def OnMouseDown(self, event):
        self.c1 = event.GetPosition()

    def OnMouseUp(self, event):
        self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))

    def OnPaint(self, event):
        if self.c1 is None or self.c2 is None: return

        dc = wx.PaintDC(self.panel)
        dc.SetPen(wx.Pen('red', 1))
        dc.SetBrush(wx.Brush(wx.Color(0, 0, 0), wx.TRANSPARENT))

        dc.DrawRectangle(self.c1.x, self.c1.y, self.c2.x - self.c1.x, self.c2.y - self.c1.y)

    def PrintPosition(self, pos):
        return str(pos.x) + " " + str(pos.y)


class MyApp(wx.App):

    def OnInit(self):
        frame = SelectableFrame()
        frame.Show(True)
        self.SetTopWindow(frame)

        return True



app = MyApp(0)
app.MainLoop()

1 个回答

5

在创建窗口的时候,不应该使用 wx.TRANSPARENT,这个主要是用在 wxDC 的绘图命令上。如果你想让一个窗口变得透明,只需要调用 win.SetTransparent(amount) 这个方法,其中 amount 的值可以在 0 到 255 之间,255 表示不透明,0 表示完全透明。你可以查看这个链接了解更多信息:http://www.wxpython.org/docs/api/wx.Window-class.html#SetTransparent

我修改了你的代码,这个代码只有在你的系统支持透明窗口的情况下才能工作,你可以通过 CanSetTransparent 来检查这一点。我是在 Windows XP 上测试的。

import wx

class SelectableFrame(wx.Frame):

    c1 = None
    c2 = None

    def __init__(self, parent=None, id=-1, title=""):
        wx.Frame.__init__(self, parent, id, title, size=wx.DisplaySize())

        self.panel = wx.Panel(self, size=self.GetSize())

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

        self.SetCursor(wx.StockCursor(wx.CURSOR_CROSS))

        self.SetTransparent(50)

    def OnMouseMove(self, event):
        if event.Dragging() and event.LeftIsDown():
            self.c2 = event.GetPosition()
            self.Refresh()

    def OnMouseDown(self, event):
        self.c1 = event.GetPosition()

    def OnMouseUp(self, event):
        self.SetCursor(wx.StockCursor(wx.CURSOR_ARROW))

    def OnPaint(self, event):
        if self.c1 is None or self.c2 is None: return

        dc = wx.PaintDC(self.panel)
        dc.SetPen(wx.Pen('red', 1))
        dc.SetBrush(wx.Brush(wx.Color(0, 0, 0), wx.TRANSPARENT))

        dc.DrawRectangle(self.c1.x, self.c1.y, self.c2.x - self.c1.x, self.c2.y - self.c1.y)

    def PrintPosition(self, pos):
        return str(pos.x) + " " + str(pos.y)


class MyApp(wx.App):

    def OnInit(self):
        frame = SelectableFrame()
        frame.Show(True)
        self.SetTopWindow(frame)

        return True


app = MyApp(0)
app.MainLoop()

撰写回答