参照services\move_tracker.py和click_tracker.py,照猫画虎新增了一个鼠标滚轮操作记录,翻文档或代码时也能证明没摸鱼……
还是直接贴在这里了:
services\scroll_tracker.py
import time
import tkinter as tk
from service.image_cache import ImageCache
from service.types import Color
import threading
from collections import deque
class ScrollTracker(tk.BooleanVar):
def __init__(self, cache: ImageCache):
"""A tracker that maintains a state of whether it should track or not"""
super(ScrollTracker, self).__init__(value=True)
self.cache = cache
# 滚动事件缓存
self.point_cache = dict()
self.render_timer = threading.Thread(target=self.render)
self.render_timer.setDaemon(True)
self.render_timer.start()
def __del__(self):
# 关闭定时器线程
self.render_timer.join() # 但是这一句不管用
pass
def render(self):
# 渲染,清空缓存,将线段缓存绘制到图像上
# 线程一旦开启就不再退出,等待主线程关闭
while True:
# 一旦队列中有元素,则渲染,直到队列只有一个点,表示鼠标不动
# 每次仅移除一个点
while len(self.point_cache) > 1:
key, value = self.point_cache.popitem()
(x, y) = key
(dx, dy) = value
R = int(255*(dx + 1) / 2) # 没有能测试横向滚的设备,Shift+滚轮还是(0, +-1)
G = int(255*(dy + 1) / 2) # 上下滚动时(dx, dy) = (0, +-1)
B = 255
colour = (R, G, B, 255) # 借一下法线贴图的颜色映射
# print(f"scroll at ({x}, {y}), dir({dx}, {dy}), UV({R}, {G}, {B})")
self.cache.ellipse(x, y, color = colour)
time.sleep(0.01) # 增加睡眠减少线程占用
def track(self, x: int, y: int, dx: int, dy: int):
if self.get():
# 此处将在每次鼠标移动时调用,非常频繁,因此需要优化
# 使用字典,同一时间在一个位置上的操作只绘制一次
self.point_cache.update({(x, y): (dx, dy)})
顺便更新了一些其他文件,调用上面的:
services\trackers.py
from typing import Dict
from pynput import mouse
from service.click_tracker import ClickTracker
from service.move_tracker import MoveTracker
from service.scroll_tracker import ScrollTracker
class Trackers(mouse.Listener):
def __init__(self,
click_trackers: Dict[mouse.Button, ClickTracker],
move_tracker: MoveTracker,
scroll_tracker: ScrollTracker
):
"""
Implemented by pynput.mouse
The `mouse.Listener` will create a thread.
"""
self.click_trackers = click_trackers
self.move_tracker = move_tracker
self.scroll_tracker = scroll_tracker
def reset(self):
"""Reset the mouse listener"""
super(Trackers, self).__init__(
on_move=self.move_tracker.on_move,
on_click=self.on_click,
on_scroll=self.on_scroll
)
def on_click(self, x, y, button, pressed):
"""Pick the right tracker and track"""
if pressed:
self.click_trackers[button].track(x, y)
def on_scroll(self, x, y, dx, dy):
self.scroll_tracker.track(x, y, dx, dy)
以及main.py初始化的应用构造函数:
class App(tk.Tk):
def __init__(self):
super(App, self).__init__()
# 配置ui信息
self.title("Mouse Tracker")
self.geometry("400x400")
icon_path = './assert/a952d-5afjj.icns'
if sys.platform.startswith("darwin"):
icon_image = ImageTk.PhotoImage(Image.open(icon_path))
self.iconphoto(True, icon_image)
else:
self.wm_iconbitmap('./assert/favicon.ico')
self.config(
background='#2e3e26',
)
# 绑定数据信息
self.imageCache = ImageCache(
get_main_screen_size()
)
self.line_opacity_value = tk.IntVar(value=50)
self.line_opacity = InputRange(
'线条不透明度(实时)',
variable=self.line_opacity_value,
from_=1,
to=100,
)
self.line_width_value = tk.IntVar(value=2)
self.line_width = InputRange(
'线条宽度(实时)',
variable=self.line_width_value,
from_=1,
to=25,
)
self.trackers = Trackers(
click_trackers={
mouse.Button.left: ClickTracker(cache=self.imageCache, color=Colors.Left),
mouse.Button.right: ClickTracker(cache=self.imageCache, color=Colors.Right),
mouse.Button.middle: ClickTracker(
cache=self.imageCache, color=Colors.Middle
),
},
move_tracker=MoveTracker(self.imageCache, self.line_opacity_value, self.line_width_value),
scroll_tracker=ScrollTracker(cache=self.imageCache),
)
# 挂载组件
self.radio_list = [ #勾选checklist
Radio(self, text=text, variable=tracker)
for text, tracker in zip(
["记录左键点击位置", "记录右键点击位置", "记录中键点击位置", "记录鼠标移动轨迹", "记录滚轮滚动位置"],
[*self.trackers.click_trackers.values(), self.trackers.move_tracker, self.trackers.scroll_tracker],
)
]
self.switch_button = SwitchButton(
[self.start_tracking, self.stop_tracking],
['开始记录', '结束记录'],
)
self.open_out_files = SwitchButton(
[open_out_folder], ['打开out文件夹']
)
def mainloop(self, n: int = 0) -> None:
time.sleep(0.01) #增加睡眠减少线程占用
return super().mainloop(n)
参照services\move_tracker.py和click_tracker.py,照猫画虎新增了一个鼠标滚轮操作记录,翻文档或代码时也能证明没摸鱼……
还是直接贴在这里了:
services\scroll_tracker.py
顺便更新了一些其他文件,调用上面的:
services\trackers.py
以及main.py初始化的应用构造函数: