1. 准备
- python 3.8(python3应该都可以)
- tkinter
- pynput
- threading
- pillow
tkinter不需要安装,是python3自带的,其余的都可以通过pip下载。
2. 思路
实现功能大体分为两个部分:1. 截图;2. 显示截图结果。
2.1 截图部分
- 识别鼠标点击事件;
- 获取截取部分的左上角右下角坐标,通过识别鼠标点击位置的坐标实现;
- 截图函数截图并保存。
2.2 显示部分
- 使用thinter创建窗口;
- 设置窗口参数,包括:置于顶层显示、隐藏标题栏;
- 将图片置于窗口显示;
- 鼠标操作,包括:拖拽图片、双击退出。
3. 代码
入口main.py:
from screenShot import ScreenShot
from showShotRes import ShowRes
import threading
import pynput.keyboard as pk
from pynput import keyboard
def on_press(key):
pass
def on_release(key):
global globalFlag
if key == keyboard.Key.f2:
# 按下F2就停止监听,进入下一步
return False
# if key == keyboard.Key.esc:
# raise Exception("停止执行")
def START():
screenShotObj = ScreenShot()
showResObj = ShowRes()
screenShotObj.STARTFUNC()
showResObj.STARTFUNC()
if __name__ == '__main__':
globalFlag = True
while globalFlag:
with pk.Listener(on_press=on_press, on_release=on_release) as pklistener:
pklistener.join()
# 开始截图
r = threading.Thread(target=START())
r.start()
截图screenShot.py
import pynput.mouse as pm
import threading
from PIL import ImageGrab
class ScreenShot():
def __init__(self):
# 临时变量
self.x_temp = 0
self.y_temp = 0
# 两组坐标
self.X1 = 0
self.Y1 = 0
self.X2 = 0
self.Y2 = 0
# 键盘监听
self.shotFlag = False
def screenshot(self):
"""
截图功能 -- 截图并保存
:return:
"""
ImageGrab.grab(bbox=(self.X1, self.Y1, self.X2, self.Y2)).save("screenshot.png")
def on_click(self, x, y, button, pressed):
"""
识别鼠标点击位置
:param x: 点击位置x坐标
:param y: 点击位置y坐标
:param pressed: 是否有点击动作
:return:
"""
if pressed:
self.x_temp = x
self.y_temp = y
if not pressed:
# 停止监听
return False
def STARTFUNC(self):
"""
线程函数,此线程中识别2次点击
:return: None
"""
with pm.Listener(on_click=self.on_click) as pmlistener1:
pmlistener1.join()
self.X1 = self.x_temp
self.Y1 = self.y_temp
with pm.Listener(on_click=self.on_click) as pmlistener2:
pmlistener2.join()
global X2, Y2
self.X2 = self.x_temp
self.Y2 = self.y_temp
self.screenshot()
if __name__ == '__main__':
a = ScreenShot()
a.STARTFUNC()
显示截图结果showShotRes.py
# <Button-1>:鼠标左击事件
# <Button-2>:鼠标中击事件
# <Button-3>:鼠标右击事件
# <Double-Button-1>:左键双击事件
# <Triple-Button-1>:左键三击事件
import tkinter as tk
class ShowRes():
def __init__(self):
pass
def MouseDown(self, event):
"""
鼠标点击选定窗口
:param event:
:return:
"""
global mousX # 全局变量,鼠标在窗体内的x坐标
global mousY # 全局变量,鼠标在窗体内的y坐标
mousX = event.x # 获取鼠标相对于窗体左上角的X坐标
mousY = event.y # 获取鼠标相对于窗左上角体的Y坐标
def MouseMove(self, event, root):
"""
鼠标移动拖拽窗口
:param event:
:return:
"""
root.geometry(f'+{event.x_root - mousX}+{event.y_root - mousY}') # 窗体移动代码
# event.x_root 为窗体相对于屏幕左上角的X坐标
# event.y_root 为窗体相对于屏幕左上角的Y坐标
def exit(self, event, root):
"""
毁掉root窗口
:param event:
:return:
"""
root.destroy()
def STARTFUNC(self):
"""
对 root 窗口的设定
:return: None
"""
root = tk.Tk()
# 基本动作 -- 拖拽移动、双击退出
root.bind("<Button-1>", self.MouseDown) # 按下鼠标左键绑定MouseDown函数
root.bind("<B1-Motion>", lambda event: self.MouseMove(event, root)) # 鼠标左键按住拖曳事件,3个函数都不要忘记函数写参数
root.bind("<Double-Button-1>", lambda event: self.exit(event, root)) # 双击鼠标左键,关闭窗体
root.title("test")
root.attributes("-topmost", True)
root.overrideredirect(True)#实现隐藏了整个标题栏的窗口
# 窗口显示图片(设置背景的方法)
background = tk.PhotoImage(file="screenshot.png")
# 将图片放到界面上
bg = tk.Label(root, image=background)
bg.pack(fill="x")
# 显示
root.mainloop()
if __name__ == '__main__':
a = ShowRes()
a.STARTFUNC()
4. README
使用步骤
- 执行
main.py
文件; - 第一次点击会被过滤掉,可以用来关闭pycharm窗口(待优化);
- 第二、三次点击应该为需要截图部分的左上角和右下角位置;
- 截图内容自动显示,置于顶层;
- 鼠标左键点住可拖拽图片;
- 双击截图内容可停止程序运行,关闭窗口;
- 再次运行需要重新执行
main.py
文件(待优化)。
UPDATE(2023.09.20):
- 执行
main.py
文件; - 按下
F2
按键; - 接下来的两次鼠标点击应为需要截图部分的左上角和右下角位置;
- 截图内容自动显示,置于顶层;
- 鼠标左键点住可拖拽图片;
- 双击截图内容可停止程序运行,关闭窗口;
- 双击截图后可以从步骤2循环执行。
终端执行方法
- cd到项目目录下,
main.py
文件所在目录中; - 和
main.py
文件同级的有一个venv文件夹,是项目的环境目录; - 执行
source venv/bin/activate
激活venv环境; - 执行
python main.py
即可运行代码; - 操作步骤见2.使用步骤。