【pyautogui】PyAutoGUI 的简单使用

文章目录

  • 1 简介
  • 2 通用功能
    • 2.1 暂停/休眠/耗时
    • 2.2 自动防故障功能
  • 3 鼠标控制
    • 3.1 移动鼠标
    • 3.2 获取鼠标指针位置
    • 3.3 点击鼠标
    • 3.4 拖动鼠标
    • 3.5 滚动鼠标
    • 3.6 常用方法
  • 4 键盘控制
    • 4.1 输入字符串 write
    • 4.2 按键操作 press
    • 4.3 按下 & 释放
    • 4.4 组合键 hotkey
    • 4.5 键名
  • 5 屏幕图像处理
    • 5.1 获取屏幕尺寸(分辨率×分辨率)
    • 5.2 获取屏幕快照
    • 5.3 像素及匹配
    • 5.4 图像定位
      • `locateOnScreen`
      • `locateCenterOnScreen`
      • `locateAllOnScreen`
  • 6 对话框
    • 6.1 alert()函数
    • 6.2 confirm()函数
    • 6.3 prompt()函数
    • 6.4 password()函数
  • 特例 Windows 平台
    • W:0 窗口对象介绍
    • W:1 获取窗口
    • W:2 操作窗口
  • 汉字的输入
  • 简单定位 mouseInfo
  • 脚本录制

1 简介

PyAutoGUI是一个纯Python的GUI自动化工具,通过它可以让程序自动控制鼠标和键盘的一系列操作来达到自动化测试的目的。

PyAutoGUI设计简洁,全部被封装在pyautogui单个模块中,因此Python程序中只要import pyautogui之后便可通过.符号访问pyautogui中的函数、变量。

pyautogui大致分为通用功能、鼠标控制、键盘控制、屏幕窗口、消息窗 5 大类。

官档: Cheat Sheet — PyAutoGUI documentation

参考: 【pyautogui】pyautogui基础简介、安装、鼠标移动、点击、截图、图像匹配查找等 - 知乎 (zhihu.com)

参考: 《 Python编程快速上手:让繁琐工作自动化(第2版) (阿尔·斯维加特) 》

2 通用功能

2.1 暂停/休眠/耗时

  1. 全局暂停 pyautogui.PAUSE

    pyautogui.PAUSE 这个变量默认值是 0.1 秒,每条指令之间的时间间隔

    import pyautogui
    print(pyautogui.PAUSE)   # 默认 0.1 秒 
    pyautogui.PAUSE = 0.2    # 设置全局暂停 0.2 秒
    

    注意pyautogui.PAUSE 为所有的 pyautogui自带api函数增加延迟。如果不设置,则默认延迟时间是0.1秒

  2. 临时休眠 pyautogui.sleep()

    如果需要在脚本的开始处设置一个暂停, 这样用户可以设置脚本将单击的窗口。PyAutoGUI有一个sleep()函数, 它的作用与time.sleep()函数相同(它只是让你不必在脚本中添加import time

  3. 倒计时 countdown()

    countdown()函数, 它可以打印出倒计时的数字, 给用户一个视觉上的指示, 说明脚本即将继续执行。

    import pyautogui
    pyautogui.countdown(5)
    
  4. duration 、interval关键字参数

    很多方法都有 duration 、interval关键字参数, 可以让操作之间有一个延迟

    pyautogui.moveTo(100, 100, duration=0.25)
    pyautogui.click(100, 100, duration=0.25)
    

2.2 自动防故障功能

import pyautogui
pyautogui.FAILSAFE  # 默认是True,表示启动防故障功能

  如果你的程序出现错误, 无法使用键盘和鼠标关闭程序, 你可以使用PyAutoGUI的故障安全功能, 快速地将鼠标指针滑动到屏幕的4个角之一。 每个PyAutoGUI函数调用在执行动作后都有1/10秒的延迟, 以便让你有足够的时间将鼠标指针移动到一个角落。

  如果你发现自己需要停止PyAutoGUI程序, 只需将鼠标指针移向角落即可。

  如果设置成False, 则需要使用注销功能,才能结束程序。

3 鼠标控制

3.1 移动鼠标

  • pyautogui.moveTo()函数将鼠标指针立即移动到屏幕的指定位置。 表示x、 y坐标的整数值分别构成了函数的第一个和第二个参数。 可选的duration整数或浮点数关键字参数指定了将鼠标指针移到目的位置所需的秒数; 如果不指定, 默认值是0, 表示立即移动(在pyautogui函数中, 所有的duration关键字参数都是可选的)

    import pyautogui
    for i in range(10):  # Move mouse in a square.pyautogui.moveTo(100, 100, duration=0.25)pyautogui.moveTo(200, 100, duration=0.25)pyautogui.moveTo(200, 200, duration=0.25)pyautogui.moveTo(100, 200, duration=0.25)
    

    这个例子根据提供的坐标, 以正方形的模式顺时针移动鼠标指针, 移动了10次。 每次移动耗时0.25秒, 因为有关键字参数指定duration=0.25。 如果没有指定函数调用的第三个参数, 鼠标指针就会马上从一个点移到另一个点

  • pyautogui.move()函数 以 “相对于当前的位置” 移动鼠标指针。

    import pyautogui
    for i in range(10):  # Move mouse in a square.pyautogui.move(100, 0, duration=0.25)  # rightpyautogui.move(0, 100, duration=0.25)  # downpyautogui.move(-100, 0, duration=0.25)  # leftpyautogui.move(0, -100, duration=0.25)  # up
    

    上面的例子同样以正方形的模式移动鼠标指针, 只是它从代码开始运行时鼠标指针所在的位置开始, 按正方形移动。

3.2 获取鼠标指针位置

  调用pyautogui.position()函数, 可以确定鼠标指针当前的位置。 它将返回函数调用时, 鼠标指针x、 y坐标的元组。

import pyautogui
for _ in range(10):print(pyautogui.position())		# 打印信息: Point(x=1763, y=373)pyautogui.sleep(1)if pyautogui.position() == pyautogui.Point(0, 0): # 鼠标移动到左上角,终端循环break

说明 Point 是个有名元组,Point = collections.namedtuple("Point", "x y"),当元组使用即可

3.3 点击鼠标

  • 单击鼠标

    默认情况下,pyautogui.click() 单击将使用鼠标左键, 单击发生在鼠标指针当前所在位置。

    如果希望单击在鼠标指针当前位置以外的地方发生, 可以传入x、 y坐标作为可选的第一个和第二个参数。

    pyautogui.click(10,10)   # 鼠标点击指定位置,默认 PRIMARY 键
    pyautogui.click(10,10,button='left')       # 单击左键
    pyautogui.click(1000,300,button='right')   # 单击右键
    pyautogui.click(1000,300,button='middle')  # 单击中键## 为了更方便,下面的函数包装了click,不需要传参 button
    pyautogui.leftClick(10,10)		# 单击左键
    pyautogui.rightClick(10,10)		# 单击右键
    pyautogui.middleClick(10,10)	# 单击中键## click 原型
    def click( x=None, y=None, clicks=1, interval=0.0, button=PRIMARY, duration=0.0, tween=linear, logScreenshot=None, _pause=True )
  • 双击鼠标

    pyautogui.doubleClick(10,10)
    
  • 三击鼠标

    pyautogui.tripleClick(10,10)
    
  • 按下 & 释放

    pyautogui.mouseDown()   # 鼠标按下
    pyautogui.mouseUp()    # 鼠标释放
    

    click()函数只是这两个函数调用的方便封装 .

3.4 拖动鼠标

  “拖动” 意味着移动鼠标指针, 同时按住一个按键不放。 例如, 可以通过拖动文件图标, 在文件夹之间移动文件, 或在日历应用中移动预约。

  • pyautogui.dragTo(x, y) 绝对位置
  • pyautogui.drag(x, y) 相对位置
import pyautoguipyautogui.sleep(5)
distance = 300
change = 20
pyautogui.click()while distance > 0:pyautogui.drag(distance, 0, duration=0.2)distance = distance - changepyautogui.drag(0, distance, duration=0.2)pyautogui.drag(-distance, 0, duration=0.2)distance = distance - changepyautogui.drag(0, -distance, duration=0.2)

  在运行这个程序时, 会有5秒的休眠, 让你选中铅笔或画笔工具, 并让鼠标指针停留在画图工具的窗口上。

  然后 pyautogui 将控制鼠标, 单击画图程序获得焦点。 画图程序获取焦点后,将绘制一个正方形旋转图案, 如下所示。

  通过控制鼠标在Paint中绘制图像, 可以利用这个Paint程序的各种笔刷样式来创建图像, 实现其他高级功能, 如渐变或颜色填充。 你可以自己预选笔刷设置, 然后运行螺旋绘图程序

在这里插入图片描述

3.5 滚动鼠标

  最后一个pyautogui鼠标函数是scroll()。 你向它提供一个整型参数, 说明向上或向下滚动多少单位。 单位的意义在每个操作系统和应用上不一样, 所以你必须试验, 看看在你当前的情况下能滚动多远。

  滚动发生在鼠标的当前位置。 传递正整数表示向上滚动, 传递负整数表示向下滚动。

pyautogui.scroll(-100)

另外还有一个水平滚动, (Currently just Linux)

pyautogui.hscroll(100)   # 向右滚动100
pyautogui.hscroll(-100)   # 向左滚动100

3.6 常用方法

函数介绍
moveTo(x,y,duration)将鼠标指针立即移动到屏幕的指定位置,耗时 duration 秒
move(dx,dy,duration)相对于"当前的位置"移动鼠标指针,耗时 duration 秒
position()获取鼠标位置
click(x,y,clicks,button)在 (x, y) 处点击鼠标 button 键 clicks 次
leftClick(x,y)左击
rightClick(x,y)右击
middleClick(x,y)中击
doubleClick(x,y)双击
dragTo(x, y)拖动鼠标,绝对位置
drag(x, y)拖动鼠标,相对位置
scroll(offset)滚动鼠标,传递正整数表示向上滚动, 传递负整数表示向下滚动

4 键盘控制

4.1 输入字符串 write

  pyautogui.write() 函数向计算机发送虚拟按键操作。

   这些操作产生什么效果, 取决于当前获得焦点的窗口和文本输入框。 可能需要先向文本框发送一次鼠标单击事件, 确保它获得焦点。

  默认情况下, write() 函数将立即输出完整字符串。 但是, 你可以传入可选的第二个参数, 在每个字符之间添加短时间暂停。 例如, pyautogui.write(‘Hello, world!’,0.25)将在输出H后等待0.25秒, 输出e以后再等待0.25秒, 以此类推。 这种渐进的打字机效果, 对于较慢的应用可能有用, 它们处理按键事件的速度不够快, 跟不上PyAutoGUI

  对于A或!这样的字符, PyAutoGUI将自动模拟按住Shift键。

下面的代码, 针对 windows 系统

import pyautogui
import osos.system('start /max notepad.exe') # windows 平台
pyautogui.sleep(1)
pyautogui.click()
for i in range(10):pyautogui.write("Hello World!\n")

在这里插入图片描述

4.2 按键操作 press

pyautogui.press('enter', 5)   # 连按5次回车

4.3 按下 & 释放

pyautogui.keyDown('A') : 模拟按键按下;
pyautogui.keyUp('A') : 模拟按键释放;

方便起见, PyAutoGUI提供了press()函数, 它调用了这两个函数, 模拟完整的按键事件。

4.4 组合键 hotkey

  “快捷键”或“热键”是一种按键组合, 它调用某种应用功能。 复制选择内容的常用快捷键是Ctrl-C( 在Windows和Linux操作系统上) 或Command-C( 在macOS上) 。 用户按住Ctrl键, 然后按C键, 然后释放C键和Ctrl键。 要用PyAutoGUIkeyDown()keyUp()函数来做到这一点, 必须输入以下代码:

pyautogui.keyDown('ctrl')
pyautogui.keyDown('c')
pyautogui.keyUp('c')
pyautogui.keyUp('ctrl')

  这相当复杂。 作为替代, 可以使用pyautogui.hotkey()函数, 它接收多个键字符串参数, 按顺序按下, 再按相反的顺序释放。 例如对于Ctrl-C快捷键, 代码就像下面这样简单:

pyautogui.hotkey('ctrl', 'c')

4.5 键名

  不是所有的键都很容易用单个文本字符来表示。

  在PyAutoGUI中, 一些特俗的键表示为短的字符串: 'esc’表示Esc键, 'enter’表示Enter键。

`pyautogui.press('win')`	# 按下 windows 键

  针对特殊按键表示的字符串, 可以向write()函数传递这些键字符串的列表。 例如, 以下的调用表示按a键, 然后是b键, 然后是左箭头两次, 最后是X和Y键:

pyautogui.write(['a', 'b', 'left', 'left', 'X', 'Y'])	# 每一个字符串代表一个按键,可以解决特殊按键的表示方法
# 因为按下左箭头将移动键盘光标, 代码会输出 `XYab`   

可以查看pyautogui.KEY_NAMES列表

print(pyautogui.KEY_NAMES)

常用的键字符串列表

键盘按键字符串含义
`1234567890-= ~!@#$%^&*()_+ a~z A~Z [] {}\;':",./<>?
‘f1’, ‘f2’ … ‘f24’, ‘fn’,功能键
‘enter’ ( or ‘return’ or ‘\n’ )回车键
‘esc’Esc键
‘shift’, ‘shiftleft’, ‘shiftright’Shift键
‘ctrl’, ‘ctrlleft’, ‘ctrlright’Ctrl键
‘alt’,‘altleft’, ‘altright’,Alt键
‘\t’, ‘tab’Tab键
‘backspace’ 、 ‘delete’Backspace键和Delete键
‘pageup’ 、 ‘pagedown’Page Up键和Page Down键
‘home’ 、 ‘end’Home键和End键
‘up’ 、 ‘down’ 、 ‘left’ 、 ‘right’上下左右箭头键
‘volumemute’ 、 ‘volumedown’ 、 ‘volumeup’静音、 减小音量、 放大音量键(有些键盘没有这些键, 但 你的操作系统仍能理解这些模拟的按键)
‘pause’Pause键
‘capslock’ 、 ‘numlock’ 、 ‘scrolllock’Caps Lock键、 Num lock键和Scroll Lock键
‘insert’Ins键或Insert键
‘printscreen’Prtsc键或Print Screen键
win’, ‘winleft’, ‘winright’Win键(在Windows操作系统上)
‘command’Command键(在macOS上)
‘option’Option键(在macOS上)

5 屏幕图像处理

5.1 获取屏幕尺寸(分辨率×分辨率)

print(pyautogui.size())   # Size(width=3840, height=2160) 

pyautogui.size()函数返回两个整数的元组, 包含屏幕的宽度和高度的像素数。 返回的是屏幕的实际尺寸,和缩放比率没有关系

获取缩放比例的方法

import ctypes
scale_factor = ctypes.windll.shcore.GetScaleFactorForDevice(0)

5.2 获取屏幕快照

PyAutoGUI拥有屏幕快照的功能,可以根据当前屏幕的内容创建图形文件。 这些函数返回一个pillow的Image对象, 包含当前屏幕的内容。

# 全屏截图
im = pyautogui.screenshot()  
# 保存截图
im.save("hello.jpg")		# 区域截图,并保存到im.png
im = pyautogui.screenshot('im.png', region=(0, 0, 830, 300))	

现在可以调用 im 对象的 Image 类的方法。

5.3 像素及匹配

  1. 获取像素 pixel()

    import pyautoguipix = pyautogui.pixel(0, 0)
    print(pix)  # (24, 24, 24)
    
  2. 像素匹配 pixelMatchesColor()

    isMatch = pyautogui.pixelMatchesColor(0, 0, (24, 24, 24))
    print(isMatch)  # TrueisMatch = pyautogui.pixelMatchesColor(0, 0, (25, 24, 24))
    print(isMatch)  # False# tolerance 容错 
    isMatch = pyautogui.pixelMatchesColor(0, 0, (25, 25, 23), tolerance=1) # 允许差值为1
    print(isMatch)  # True
    

5.4 图像定位

如果事先不知道PyAutoGUI应该单击哪里, 该怎么办? 可以使用图像识别功能, 向PyAutoGUI提供希望单击的图像, 让它去弄清楚坐标。

locateOnScreen

locateOnScreen()函数返回, 是屏幕上首次发现该图像时左边的x坐标、 顶边的y坐标、 宽度以及高度。

例如:事先截取了图像,比如屏幕左下角的 window 图片,保存为submit.png, 那么locateOnScreen('submit.png')函数将返回图像所在处的坐标。

在这里插入图片描述

import pyautoguiregion = pyautogui.locateOnScreen('submit.png')
print(region)                     # Box(left=0, top=2080, width=96, height=80)
print(pyautogui.center(region))   # Point(x=48, y=2120)

请注意, 要成功识别, 屏幕上的图像必须与提供的图像完全匹配。 即使只差一个像素, locateOnScreen() 函数也会引发ImageNotFoundException异常。

locateCenterOnScreen

定位并求中间点的位置

center = pyautogui.locateCenterOnScreen('submit.png')
print(center)   # Point(x=48, y=2120)

增加容错率 指定查找范围 以及可信度

region = pyautogui.locateOnScreen('submit.png', grayscale=True, region=(0, 1000, 100, 2080), confidence=0.9)
  • grayscale=True 传递给 locateOnScreen,以略微加速(大约 30%)。这降低了图像和截图的颜色饱和度,加快了定位速度,但可能会导致错误匹配。

  • region=(0, 1000, 100, 2080) 传递给 locateOnScreen,指定查找范围

  • confidence=0.9 传递给 locateOnScreen,指定可信赖度

locateAllOnScreen

如果该图像在屏幕上能够找到多处,locateAllOnScreen() 函数将返回一个Generator对象。 可以将它传递给list(), 返回一个元组的列表

list(pyautogui.locateAllOnScreen('submit.png'))

6 对话框

PyAutoGUI 利用 PyMsgBox 中的消息框函数提供了一种跨平台的纯 Python 方法来显示 javascript 样式的消息框。

6.1 alert()函数

单击按钮后返回 button 的值

ret = pyautogui.alert(text='text', title='title', button='alert')
print(ret) # alert

在这里插入图片描述

6.2 confirm()函数

显示带有多个按钮的消息框。按钮的数量和文字可以自己设置。单击按钮返回该按钮的文本。

pyautogui.confirm(text='text', title='title')  # 默认按钮值
pyautogui.confirm(text='text', title='title', buttons=['OK', 'Cancel', '狠心退出'])	# 自定义按钮值

在这里插入图片描述

6.3 prompt()函数

显示一个包含 确认,取消 按钮和文本输入栏的消息框,用户可以输入指定内容。当点击确认按钮后,返回输入框中的值;若点击取消,则返回 None

pyautogui.prompt(text='text', title='title', default='请输入文本信息')

在这里插入图片描述

6.4 password()函数

显示一个包含 确认,取消 按钮和文本输入栏的消息框,输入的字符显示为"*"。如果点击确认则返回输入的文本;如果单击“取消”,则为 None

pyautogui.password(text='text', title='title', default='密码', mask='*')

在这里插入图片描述

利用对话框,可以很方便的设置需要操作的对象. 前面的案例都是使用 sleep() 方法来阻塞程序,等待用户选择好操作的对象。现在利用对话框就很方便了。例如:

import pyautoguidef doAuto():for i in range(10):pyautogui.write("Hello World!\n", 0.1)def main():ret = pyautogui.confirm(text='text', title='title')if ret != "OK":returndoAuto()if __name__ == '__main__':main()

完全可以打开记事本,然后点击确定,就可以让代码继续执行下去

特例 Windows 平台

W:0 窗口对象介绍

Win32Window 对象的属性:

  • left、 right、 top、 bottom: 一个整数, 表示窗口边的x或y坐标。

  • topleft、 topright、 bottomleft、 bottomright: 两个整数的命名元组, 表示窗
    口角的(x, y)坐标。

  • midleft、 midright、 midleft、 midright: 两个整数的命名元组, 表示窗口边中
    间的(x, y)坐标。

  • width, height: 一个整数, 表示窗口的一个维度, 以像素为单位。

  • size: 两个整数的命名元组, 表示窗口的(宽度, 高度) 。

  • area: 一个整数, 表示窗口的面积, 以像素为单位。

  • center: 两个整数的命名元组, 表示窗口的中心(x, y) 坐标。

  • centerx、 centery: 一个整数, 表示窗口中心的x或y坐标。

  • box: 4个整数的命名元组, 表示窗口(左侧、 顶部、 宽度、 高度) 。

  • title: 窗口顶部标题栏中的文本字符串。

    import pyautoguifw = pyautogui.getActiveWindow()
    print(fw)
    print(fw.left)
    print(fw.topleft)
    print(fw.midleft)
    print(fw.width, fw.height)
    print(fw.size)
    print(fw.area)
    print(fw.center)
    print(fw.centerx, fw.centery)
    print(fw.box)
    print(fw.title)
    
  • 属性方法:

    • isMinimized
    • isMaximized
    • isActive
    • title
    • visible

W:1 获取窗口

  • 获取活动窗口

    pyautogui.getActiveWindow() -> Win32Window

    获取所有可见窗口

    pyautogui.getAllWindows()

  • 获取所有包含点(x, y) 的可见窗口的Window对象列表

    pyautogui.getWindowsAt(x, y)

  • 获取所有在标题栏中包含字符串title的可见窗口的Window对象的列表

    pyautogui.getWindowsWithTitle(title)

  • 获取所有可见窗口的字符串列表

    pyautogui.getAllTitles()

W:2 操作窗口

窗口属性不仅可以告诉你窗口的大小和位置, 还可以做更多的事情。 你也可以设置它们的值, 以便调整窗口大小或移动窗口。

import pyautoguifw = pyautogui.getActiveWindow()if bool(fw.isMaximized):fw.restore()
pyautogui.sleep(2)
fw.top += 300

或者使用下面的方法

  • win.move(xOffset, yOffset)

  • win.moveTo(newLeft, newTop)

  • win.resize(widthOffset, heightOffset)

  • win.resizeTo(width, height)

  • win.maximize() # 最大化

  • win.minimize() # 最小化

  • win.restore() # 如果是最大/小化,则恢复成正常状态

  • win.close()

  • win.position() # returns (x, y) of top-left corner

  • win.moveRel(x=0, y=0) # moves relative to the x, y of top-left corner of the window

  • win.clickRel(x=0, y=0, clicks=1, interval=0.0, button=’left’) # click relative to the x, y of top-left corner of the window

汉字的输入

pyautogui控制键盘的方式来看,这个库只管模拟发送按键,至于这些按键能不能变成中文,还要依靠中文输入法来实现。

这种方式比较烦。

更为便捷的方式是使用 pyperclip 库, 如下所示

import pyautogui
import pyperclippyperclip.copy("你好,世界\n")
pyautogui.hotkey('ctrl', 'v')

简单定位 mouseInfo

  编写一个能自动单击屏幕的程序的难点之一, 就是找到你想单击的物品的x坐标和y坐标。 pyautogui.mouseInfo()函数可以帮助你解决这个问题。

  pyautogui.mouseInfo()函数可以单独使用,而不是作为程序的一部分。 它启动了一个名为MouseInfo的小应用程序, 该应用程序是PyAutoGUI的一部分。

import pyautogui
pyautogui.mouseInfo()

在这里插入图片描述

  该窗口提供了关于鼠标指针当前位置的信息, 以及鼠标指针处的像素的颜色, 以3个整数的RGB元组和十六进制值的形式显示。 颜色本身会出现
在窗口中的颜色框中。

  • Copy All、 Copy XY、 Copy RGB和Copy RGB Hex按钮将对应的信息复制到剪贴板上。
  • Log All、 Log XY、 Log RGB和Log RGB Hex按钮将对应的信息写入窗口中的大文本字段
  • 可以通过单击Save Log按钮, 保存这个文本字段中的文本。
  • 可以通过使用 F1, F2 … F8 功能键类实现

有了一些关键点的坐标,可以在以后的PyAutoGUI脚本中使用这些坐标

脚本录制

PyAutoGUI 中居然没有回调函数,也就是我想要在某个点按下鼠标,然后打印出鼠标的位置, 基本上是不可能的。不过好在还有一个库 pynput, 它有键鼠监听器,只是自动化执行脚本的时候,没有过场动画之类。而且没有考虑到屏幕缩放。

所以最好的方式,是用 pynput 录制脚本,用 pyautogui执行脚本。

本来还打算写一篇 pynput的文章了,但是还是放弃了,PyAutoGUI就耗了我一天时间,实在没兴趣再写了。

有兴趣可以参考 官档 pynput Package Documentation — pynput 1.7.6 documentation

直接附上示例代码:

from tkinter import Tk, Button, Label
from pynput import mouse
# import pymsgbox
from tkinter.simpledialog import askstringrect = 0class Rect:def __init__(self, x, y, width, height):self.p1 = (x, y)self.p2 = (x+width, y+height)def __str__(self) -> str:return str(self.p1) + str(self.p2)def getScreenRatio2():import ctypesscale_factor = ctypes.windll.shcore.GetScaleFactorForDevice(0)return scale_factor/100def constains(rect: Rect, x, y):if rect.p1[0] <= x <= rect.p2[0] and rect.p1[1] <= y <= rect.p2[1]:return Truereturn Falsedef on_move(x, y):print('Pointer moved to {0}'.format((x, y)))def on_click(x, y, button, pressed):print(f'{'press' if pressed else 'release'}({button}) at {(x, y)}')if button == mouse.Button.middle:# Stop listenerreturn Falseif pressed:print(constains(rect, x, y), rect, x, y)if not constains(rect, x, y):f.write(f"pyautogui.moveTo({x, y}, duration=dur)\n")  # 默认左键f.write("pyautogui.click(duration=dur)\n\n")  # 默认左键def on_scroll(x, y, dx, dy):print('Scrolled {0} at {1}'.format('down' if dy < 0 else 'up',(x, y)))# ...or, in a non-blocking fashion:
listener = Nonedef getListener():global listenerlistener = mouse.Listener(# on_move=on_move,on_click=on_click,on_scroll=on_scroll)def move_window(event):global rectrect = Rect(tk.winfo_x()*scale, tk.winfo_y()*scale,tk.winfo_width()*scale, (tk.winfo_height()+27)*scale)f = Nonedef doStart():global fgetListener()listener.start()b1.config(state='disabled')b2.config(state='normal')f = open(filename, 'w', encoding='utf-8')f.write("import pyautogui\n")f.write("pyautogui.PAUSE = 0.2\n")f.write("dur = 0.25\n")def doStop():listener.stop()b1.config(state='normal')b2.config(state='disabled')f.close()def doQuit():if listener:listener.stop()tk.destroy()x = y = 0def StartMove(event):global x, yx = event.xy = event.ydef StopMove(event):global x, yx = Noney = Nonedef OnMotion(event):# global x, ydeltax = event.x - xdeltay = event.y - yx1 = tk.winfo_x() + deltaxy1 = tk.winfo_y() + deltaytk.geometry("+%s+%s" % (x1, y1))# tk.geometry("+%s+%s" % (event.x, event.y))if __name__ == '__main__':# filename = pymsgbox.prompt('请输入脚本名称', '脚本', default='自动生成脚本_pyautogui.py')filename = askstring(title="脚本", prompt="请输入脚本名称",initialvalue="自动生成脚本_pyautogui.py")print(filename)if filename:tk = Tk()scale = getScreenRatio2()tk.overrideredirect(1)tk.attributes('-topmost', 'true')grip = Label(bitmap="gray25")b1 = Button(tk, text="🐟", command=doStart, state='normal', fg="red")b2 = Button(tk, text="🛑", command=doStop, state='disabled', fg="red")b3 = Button(tk, text="❌", command=doQuit)grip.grid(row=0, column=0)grip.bind("<ButtonPress-1>", StartMove)grip.bind("<ButtonRelease-1>", StopMove)grip.bind("<B1-Motion>", OnMotion)b1.grid(row=0, column=1)b2.grid(row=0, column=2)b3.grid(row=0, column=3)tk.bind('<Configure>', move_window)tk.mainloop()

小程序说明:

  • 输入脚本文件名称
  • b1 开始录制
  • b2 停止录制
  • b3 退出程序
  • grip 用来实现拖动界面

最初只是想写个简单的信息打印, 然后就想着直接输出 pyautogui 的脚本文件, 然后又想着还是加个控制按钮吧, 先用 ttk.Button 觉得太大,然后又用回tk.Button, 感觉窗口框架比按钮还长, 更丑了, 又写成无框样式, 觉得界面没法移动, 又去学习无框拖动方法. 最后写完了,感觉整个代码好乱,结构一点也不清楚,不想看了,有机会再重构,至少可以把无框界面那块给封装成一个类

最后说一句写这个代码的感受,Python 真的太简洁了, 能够随心所欲地尝试。

Python 少即是多,好玩,有趣,有料!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/744817.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2.1 关系数据结构及形式化定义 数据库概论

目录 2.1.1 关系 关系&#xff1a;概念 1. 域&#xff08;Domain&#xff09; 2.笛卡尔积 元组&#xff08;Tuple&#xff09; 分量&#xff08;Component&#xff09; 基数&#xff08;Cardinal number&#xff09; 3. 关系 候选码&#xff08;Candidate key&#xf…

软件设计师17--磁盘管理

软件设计师17--磁盘管理 考点1&#xff1a;存储管理 - 磁盘管理调度算法磁盘调度 - FCFS磁盘调度 - SSTF例题&#xff1a; 考点1&#xff1a;存储管理 - 磁盘管理 存取时间寻道时间等待时间&#xff0c;训导时间是指磁头移动到磁道所需的时间&#xff1b;等待时间为等待读写的扇…

网工内推 | 上市公司网工,IE认证优先,最高18K*13薪,包吃住

01 深圳市宝腾互联科技有限公司 招聘岗位&#xff1a;网络工程师 职责描述&#xff1a; 1、是整个数据中心的网络技术及安全问题的负责人&#xff0c;确保数据中心业务的正常进行&#xff1b; 2、负责规划、设计、搭建、维护数据中心的网络环境&#xff0c;确保IDC /云平台&a…

python INI文件操作与configparser内置库

目录 INI文件 configparser内置库 类与方法 操作实例 导入INI文件 查询所有节的列表 判断某个节是否存在 查询某个节的所有键的列表 判断节下是否存在某个键 增加节点 删除节点 增加节点的键 修改键值 保存修改结果 获取键值 获取节点所有键值 其他读取方式 …

[Kali] 安装Nessus及使用

在官方网站下载对应的 Nessus 版本:Download Tenable Nessus | TenableDownload Nessus and Nessus Managerhttp://www.tenable.com/products/nessus/select-your-operating-system这里选择 Kali 对应的版本 一、安装 Nessus 1、下载得到的是 deb 文件,与

【爬虫开发】爬虫从0到1全知识md笔记第1篇:爬虫概述【附代码文档】

爬虫开发从0到1全知识教程完整教程&#xff08;附代码资料&#xff09;主要内容讲述&#xff1a;爬虫概述。selenium的其它使用方法。Selenium课程概要。常见的反爬手段和解决思路。验证码处理。chrome浏览器使用方法介绍。JS的解析。Mongodb的介绍和安装,小结。mongodb的简单使…

为什localhost被forbidden而127.0.0.1不被绊?

原因&#xff1a; 判段网关的时候判127.0.0.1&#xff0c;所以最好改localhost 其他参考&#xff1a; 【计算机网络】localhost不能访问&#xff0c;127.0.0.1可以访问&#xff1f;_ping localhost和ping 127.0.0.1-CSDN博客

基于springboot实现驾校信息管理系统项目【项目源码+论文说明】

基于springboot实现驾校信息管理系统演示 摘要 随着人们生活水平的不断提高&#xff0c;出行方式多样化&#xff0c;也以私家车为主&#xff0c;那么既然私家车的需求不断增长&#xff0c;那么基于驾校的考核管理也就不断增强&#xff0c;那么业务系统也就慢慢的随之加大。信息…

一文了解Cornerstone3D中窗宽窗位的3种设置场景及原理

&#x1f506; 引言 在使用Cornerstone3D渲染影像时&#xff0c;有一个常用功能“设置窗宽窗位&#xff08;windowWidth&windowLevel&#xff09;”&#xff0c;通过精确调整窗宽窗位&#xff0c;医生能够更清晰地区分各种组织&#xff0c;如区别软组织、骨骼、脑组织等。…

mac【启动elasticsearch报错:can not run elasticsearch as root

mac【启动elasticsearch报错&#xff1a;can not run elasticsearch as root 问题原因 es默认不能用root用户启动&#xff0c;生产环境建议为elasticsearch创建用户。 解决方案 为elaticsearch创建用户并赋予相应权限。 尝试了以下命令创建用户&#xff0c;adduser esh 和u…

C# ListView 控件使用

1.基本设置 listView1.Columns.Add("序号", 60); //向 listView1控件中添加1列 同时设置列名称和宽度listView1.Columns.Add("温度", 100); //下同listView1.Columns.Add("偏移", 100);listView1.Columns.Add("分割", 50);listView1…

ssm蛋糕甜品商城系统(程序+文档+数据库)

** &#x1f345;点赞收藏关注 → 私信领取本源代码、数据库&#x1f345; 本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目&#xff0c;希望你能有所收获&#xff0c;少走一些弯路。&#x1f345;关注我不迷路&#x1f345;** 一、研究背景…

计算机视觉研究院 | EdgeYOLO:边缘设备上实时运行的目标检测器及Pytorch实现

本文来源公众号“计算机视觉研究院”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;EdgeYOLO&#xff1a;边缘设备上实时运行的目标检测器及Pytorch实现 代码地址&#xff1a;https://github.com/LSH9832/edgeyolo 今天分享的研究…

【LeetCode】升级打怪之路 Day 21:二叉树的最近公共祖先(LCA)问题

今日题目&#xff1a; 236. 二叉树的最近公共祖先1644. 二叉树的最近公共祖先 II235. 二叉搜索树的最近公共祖先 目录 LCA 问题LC 236. 二叉树的最近公共祖先 【classic】LC 1644. 二叉树的最近公共祖先 II 【稍有难度】LC 235. 二叉搜索树的最近公共祖先 ⭐⭐⭐ 今天做了几道有…

python备份库

个人简介 &#x1f468;&#x1f3fb;‍&#x1f4bb;个人主页&#xff1a;九黎aj &#x1f3c3;&#x1f3fb;‍♂️幸福源自奋斗,平凡造就不凡 &#x1f31f;如果文章对你有用&#xff0c;麻烦关注点赞收藏走一波&#xff0c;感谢支持&#xff01; &#x1f331;欢迎订阅我的…

SAM分割 图片bbox提示任意数量目标输出mask

前提条件&#xff1a;labelimg打标签得到bbox 1.代码 import torchfrom segment_anything import SamPredictor, sam_model_registry import cv2 import numpy as np import os import glob import xml.etree.ElementTree as ETcheckpoint "./weight/sam_vit_h_4b8939.…

分布式数据处理MapReduce简单了解

文章目录 产生背景编程模型统计词频案例 实现机制容错机制Master的容错机制Worker的容错机制 产生背景 MapReduce是一种分布式数据处理模型和编程技术&#xff0c;由Google开发&#xff0c;旨在简化大规模数据集的处理。产生MapReduce的背景&#xff1a; 数据量的急剧增长&…

通过OceanBase 3.x中not in无法走hash连接的变化,来看OB优化器的发展

作者简介&#xff1a; 张瑞远&#xff0c;曾从事银行、证券数仓设计、开发、优化类工作&#xff0c;现主要从事电信级IT系统及数据库的规划设计、架构设计、运维实施、运维服务、故障处理、性能优化等工作。 持有Orale OCM,MySQL OCP及国产代表数据库认证。 获得的专业技能与认…

C#,数值计算,矩阵相乘的斯特拉森(Strassen’s Matrix Multiplication)分治算法与源代码

Volker Strassen 1 矩阵乘法 矩阵乘法是机器学习中最基本的运算之一,对其进行优化是多种优化的关键。通常,将两个大小为N X N的矩阵相乘需要N^3次运算。从那以后,我们在更好、更聪明的矩阵乘法算法方面取得了长足的进步。沃尔克斯特拉森于1969年首次发表了他的算法。这是第…

【刷题】双指针进阶

请看入门篇 &#xff1a;双指针入门 送给我们一句话&#xff1a; 如今我努力奔跑&#xff0c;不过是为了追上那个曾经被寄予厚望的自己 —— 约翰。利文斯顿 双指针进阶 Leetcode 611 有效三角形的个数Leetcode LCR179.查找总价格为目标值的两个商品Leetcode 15.三数之和Thanks…