使用Wx和PyAutoGui从Python制作“剪贴工具”

使用Wx和PyAutoGui从Python制作“剪贴工具”,python,python-3.x,wxwidgets,pyautogui,Python,Python 3.x,Wxwidgets,Pyautogui,我正试图使用Wx和PyAutoGui模块制作一个剪贴工具,我遇到了一个特定的问题:保存的图像文件位于错误的位置,请参见下图 如您所见,我正在尝试获取一个特定区域,即红色矩形,并将该区域中的像素保存到文件my_screenshot.png中。然而,位置/坐标似乎是关闭的,你可以看到矩形,这应该是屏幕截图的区域 代码如下: import wx import pyautogui class SelectableFrame(wx.Frame): c1 = None c2 = None

我正试图使用Wx和PyAutoGui模块制作一个剪贴工具,我遇到了一个特定的问题:保存的图像文件位于错误的位置,请参见下图

如您所见,我正在尝试获取一个特定区域,即红色矩形,并将该区域中的像素保存到文件my_screenshot.png中。然而,位置/坐标似乎是关闭的,你可以看到矩形,这应该是屏幕截图的区域

代码如下:

import wx
import pyautogui

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.Cursor(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.Cursor(wx.CURSOR_ARROW))
        region = (self.c1.x, self.c1.y, self.c2.x - self.c1.x, self.c2.y - self.c1.y)
        pyautogui.screenshot('my_screenshot.png', region=region)
        print("MouseUp: " + str(region))
        self.Hide()

    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.Colour(0, 0, 0), wx.TRANSPARENT))

        region = (self.c1.x, self.c1.y, self.c2.x - self.c1.x, self.c2.y - self.c1.y)
        dc.DrawRectangle(self.c1.x, self.c1.y, self.c2.x - self.c1.x, self.c2.y - self.c1.y)
        print("Draw: " + str(region))


    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()
从我收集的数据来看,它需要宽度和高度,但是x和y的位置不对,我怎么能修正呢?多谢各位

编辑:这些函数之间似乎存在值差异

    def OnMouseDown(self, event):
        self.c1 = event.GetPosition()
        print("MouseDown[event]: " + str(self.c1))
        print("MouseDown[gui]: "+  str(pyautogui.position()))
输出:

MouseDown[event]: (729, 484)
MouseDown[gui]: Point(x=737, y=515)
x的偏移量为+8,y的偏移量为+31。这种尿失禁是怎么发生的?我的修补程序是将这些偏移量添加到pyautogui.screenshot命令中,但我认为这不是正确的修补程序,也不能保证其他屏幕尺寸的偏移量值相同。

与鼠标事件关联的位置在窗口中表示 生成事件的窗口的坐标,可以使用 wx.Window.ClientToScreen将其转换为屏幕坐标,并 可能调用wx.Window.ScreenToClient将其转换为Windows 另一个窗口的坐标

pyautogui的屏幕截图使用屏幕坐标

因此,将wx.Window.ClientToScreen与c1和c2一起使用

顺便说一句,您还应该在OnMouseUp上更新c2,并检查它是否为“无”或不等于c1