整理文件

This commit is contained in:
cyonjan 2025-07-30 22:14:37 +08:00
parent f682fafc93
commit a0af1a9fbf
4 changed files with 85 additions and 387 deletions

View File

@ -0,0 +1,83 @@
# 剪贴板监控程序
## 简介
这是一个基于Windows 64位系统的剪贴板实时监控程序使用Python 3.11及以上版本开发。程序在后台运行,当检测到剪贴板内容变化时,会记录剪贴板内容并显示通知提示。支持文本和图片媒体的记录。
## 功能特点
- 实时监控剪贴板变化
- 自动记录剪贴板历史内容
- 支持图片媒体的记录和保存
- 系统托盘图标,最小化运行
- 可暂停/继续监控
- 查看历史记录
- 支持开机自启动
## 系统要求
- Windows 64位操作系统
- Python 3.11或更高版本
- 必要的Python库pyperclip, pystray, pillow (PIL), pywin32
## 安装步骤
1. 确保已安装Python 3.11或更高版本
2. 双击运行`start_clipboard_monitor.bat`,脚本会自动检查并安装必要的库
## 使用方法
### 启动程序
双击运行`start_clipboard_monitor.bat`文件即可启动剪贴板监控程序。程序启动后会在系统托盘显示图标。
### 设置开机自启动
如果希望程序在Windows启动时自动运行请双击运行`setup_autostart.bat`文件它会在Windows的启动文件夹中创建必要的快捷方式。
### 使用界面
程序启动后会在系统托盘区域显示一个图标,右键点击图标可以看到以下选项:
- **显示主窗口**:打开主界面,查看剪贴板历史记录
- **暂停/继续监控**:临时暂停或继续监控剪贴板
- **清空历史记录**:删除所有已记录的剪贴板历史
- **退出**:完全退出程序
### 主窗口
在主窗口中,您可以:
- 查看所有剪贴板历史记录
- 使用按钮暂停/继续监控
- 清空历史记录
- 退出程序
## 文件说明
- `clipboard_monitor.py`:主程序文件
- `start_clipboard_monitor.bat`:启动脚本
- `setup_autostart.bat`:设置开机自启动脚本
- `clipboard_monitor.log`:程序运行日志
- `clipboard_history.txt`:剪贴板历史记录
- `clipboard_media/`:保存剪贴板图片的文件夹
## 注意事项
1. 程序会在后台持续运行,如需完全退出,请通过系统托盘图标的"退出"选项或主窗口的"退出程序"按钮退出
2. 剪贴板历史记录保存在程序所在目录的`clipboard_history.txt`文件中
3. 剪贴板中的图片会保存在`clipboard_media`文件夹中,文本记录中会包含图片文件的引用
4. 如果遇到问题,可以查看`clipboard_monitor.log`日志文件了解详情
## 故障排除
如果程序无法正常启动或运行,请检查:
1. 确认Python版本是否为3.11或更高
2. 确认已安装所需的库pyperclip, pystray, pillow, pywin32
3. 查看`clipboard_monitor.log`日志文件,了解错误详情
4. 如果提示缺少库,可以手动安装:`pip install pyperclip pystray pillow pywin32`
## 隐私说明
本程序仅在本地运行,不会将任何数据发送到互联网。所有剪贴板内容仅保存在本地文件中。

View File

@ -33,3 +33,5 @@ SystemExit: 0
2025-07-30 16:15:36,353 - INFO - 检测到剪贴板图片变化
2025-07-30 16:15:36,385 - INFO - 图片已保存到: clipboard_media\20250730_161536_7842fbf8.png
2025-07-30 16:15:57,592 - INFO - 检测到剪贴板文本变化
2025-07-30 21:57:53,972 - INFO - 剪贴板监控程序已启动
2025-07-30 21:58:05,028 - INFO - 检测到剪贴板文本变化

View File

@ -1,304 +0,0 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
剪贴板监控程序
该程序在后台运行实时监控Windows系统剪贴板的变化
当检测到剪贴板内容变化时记录内容并输出提示
支持文本和图片媒体的记录
"""
import time
import threading
import sys
import os
import datetime
import uuid
import io
import pyperclip
from pystray import Icon, Menu, MenuItem
from PIL import Image, ImageDraw, ImageGrab
import tkinter as tk
from tkinter import messagebox
import logging
import win32clipboard
from io import BytesIO
# 配置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler("clipboard_monitor.log", encoding='utf-8'),
logging.StreamHandler()
]
)
class ClipboardMonitor:
def __init__(self):
self.previous_clipboard = ""
self.previous_image_hash = None
self.monitoring = True
self.paused = False
self.log_file = "clipboard_history.txt"
self.media_folder = "clipboard_media"
# 确保媒体文件夹存在
if not os.path.exists(self.media_folder):
os.makedirs(self.media_folder)
self.setup_gui()
self.create_tray_icon()
def setup_gui(self):
"""设置GUI窗口但默认不显示"""
self.root = tk.Tk()
self.root.title("剪贴板监控")
self.root.geometry("400x300")
self.root.protocol("WM_DELETE_WINDOW", self.hide_window)
# 创建文本区域显示剪贴板历史
self.text_area = tk.Text(self.root, wrap=tk.WORD)
self.text_area.pack(expand=True, fill=tk.BOTH, padx=10, pady=10)
# 创建按钮框架
button_frame = tk.Frame(self.root)
button_frame.pack(fill=tk.X, padx=10, pady=5)
# 添加按钮
tk.Button(button_frame, text="暂停监控", command=self.toggle_pause).pack(side=tk.LEFT, padx=5)
tk.Button(button_frame, text="清空历史", command=self.clear_history).pack(side=tk.LEFT, padx=5)
tk.Button(button_frame, text="退出程序", command=self.exit_app).pack(side=tk.RIGHT, padx=5)
# 默认隐藏窗口
self.root.withdraw()
def create_tray_icon(self):
"""创建系统托盘图标"""
# 创建图标
image = self.create_icon_image()
# 创建菜单
menu = Menu(
MenuItem('显示主窗口', self.show_window),
MenuItem('暂停/继续监控', self.toggle_pause),
MenuItem('清空历史记录', self.clear_history),
MenuItem('退出', self.exit_app)
)
# 创建托盘图标
self.icon = Icon("clipboard_monitor", image, "剪贴板监控", menu)
# 在单独的线程中运行图标
threading.Thread(target=self.icon.run, daemon=True).start()
def create_icon_image(self):
"""创建托盘图标图像"""
# 创建一个32x32的图像白色背景
image = Image.new('RGB', (32, 32), color=(255, 255, 255))
d = ImageDraw.Draw(image)
# 绘制剪贴板图标
d.rectangle([(8, 8), (24, 24)], outline=(0, 0, 0), width=2)
d.rectangle([(12, 4), (20, 8)], fill=(0, 0, 0))
return image
def show_window(self):
"""显示主窗口"""
self.root.deiconify()
self.root.lift()
self.update_text_area()
def hide_window(self):
"""隐藏主窗口"""
self.root.withdraw()
def toggle_pause(self):
"""切换暂停/继续监控状态"""
self.paused = not self.paused
status = "暂停" if self.paused else "继续"
logging.info(f"监控已{status}")
self.show_notification(f"剪贴板监控已{status}")
def clear_history(self):
"""清空历史记录"""
try:
with open(self.log_file, 'w', encoding='utf-8') as f:
f.write("")
self.update_text_area()
logging.info("历史记录已清空")
self.show_notification("历史记录已清空")
except Exception as e:
logging.error(f"清空历史记录失败: {e}")
def exit_app(self):
"""退出应用程序"""
self.monitoring = False
if hasattr(self, 'icon'):
self.icon.stop()
self.root.quit()
# 不使用sys.exit()避免引发SystemExit异常
# 让程序自然退出
def show_notification(self, message):
"""显示通知"""
if hasattr(self, 'icon'):
self.icon.notify(message)
def update_text_area(self):
"""更新文本区域内容"""
self.text_area.delete(1.0, tk.END)
try:
if os.path.exists(self.log_file):
with open(self.log_file, 'r', encoding='utf-8') as f:
content = f.read()
self.text_area.insert(tk.END, content)
except Exception as e:
logging.error(f"读取历史记录失败: {e}")
def save_clipboard_content(self, content, media_path=None):
"""保存剪贴板内容到文件"""
try:
timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
with open(self.log_file, 'a', encoding='utf-8') as f:
f.write(f"\n[{timestamp}]\n")
# 如果有媒体文件,添加引用
if media_path:
f.write(f"[图片文件: {media_path}]\n")
else:
f.write(f"{content}\n")
f.write(f"{'='*50}\n")
# 如果窗口可见,更新文本区域
if self.root.winfo_viewable():
self.update_text_area()
except Exception as e:
logging.error(f"保存剪贴板内容失败: {e}")
def get_clipboard_image(self):
"""尝试从剪贴板获取图片"""
try:
# 尝试使用PIL的ImageGrab获取剪贴板图片
image = ImageGrab.grabclipboard()
if isinstance(image, Image.Image):
return image
return None
except Exception as e:
logging.error(f"获取剪贴板图片失败: {e}")
return None
def save_image_to_file(self, image):
"""保存图片到文件"""
try:
# 生成唯一文件名
timestamp = datetime.datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"{timestamp}_{uuid.uuid4().hex[:8]}.png"
filepath = os.path.join(self.media_folder, filename)
# 保存图片
image.save(filepath)
logging.info(f"图片已保存到: {filepath}")
return filepath
except Exception as e:
logging.error(f"保存图片失败: {e}")
return None
def get_image_hash(self, image):
"""获取图片的简单哈希值用于比较"""
if not image:
return None
try:
# 缩小图片以加快哈希计算
small_image = image.resize((32, 32), Image.LANCZOS)
# 转换为灰度
gray_image = small_image.convert("L")
# 获取像素数据
pixels = list(gray_image.getdata())
# 简单哈希:将像素值二值化并转为字符串
binary_pixels = ['1' if p > 128 else '0' for p in pixels]
return ''.join(binary_pixels)
except Exception as e:
logging.error(f"计算图片哈希失败: {e}")
return None
def monitor_clipboard(self):
"""监控剪贴板变化"""
try:
# 获取初始剪贴板内容
self.previous_clipboard = pyperclip.paste()
# 获取初始图片(如果有)
initial_image = self.get_clipboard_image()
if initial_image:
self.previous_image_hash = self.get_image_hash(initial_image)
except Exception as e:
self.previous_clipboard = ""
self.previous_image_hash = None
logging.error(f"获取初始剪贴板内容失败: {e}")
while self.monitoring:
try:
if not self.paused:
# 检查是否有图片
current_image = self.get_clipboard_image()
if current_image:
current_image_hash = self.get_image_hash(current_image)
# 如果图片变化了
if current_image_hash != self.previous_image_hash:
logging.info("检测到剪贴板图片变化")
self.show_notification("检测到新的剪贴板图片")
# 保存图片到文件
image_path = self.save_image_to_file(current_image)
if image_path:
# 保存引用到日志
self.save_clipboard_content("", image_path)
# 更新上一次的图片哈希
self.previous_image_hash = current_image_hash
else:
# 获取当前文本内容
current_clipboard = pyperclip.paste()
# 如果文本内容变化了
if current_clipboard != self.previous_clipboard:
logging.info("检测到剪贴板文本变化")
self.show_notification("检测到新的剪贴板内容")
# 保存新内容
self.save_clipboard_content(current_clipboard)
# 更新上一次的内容
self.previous_clipboard = current_clipboard
except Exception as e:
logging.error(f"监控剪贴板时出错: {e}")
# 休眠一段时间再检查
time.sleep(0.5)
def run(self):
"""运行监控程序"""
# 启动监控线程
monitor_thread = threading.Thread(target=self.monitor_clipboard, daemon=True)
monitor_thread.start()
# 显示启动通知
self.show_notification("剪贴板监控已启动")
logging.info("剪贴板监控程序已启动")
# 运行主循环
self.root.mainloop()
if __name__ == "__main__":
try:
monitor = ClipboardMonitor()
monitor.run()
except Exception as e:
logging.critical(f"程序启动失败: {e}")
messagebox.showerror("错误", f"程序启动失败: {e}")
sys.exit(1)

View File

@ -1,83 +0,0 @@
# 剪贴板监控程序
## 简介
这是一个基于Windows 64位系统的剪贴板实时监控程序使用Python 3.11及以上版本开发。程序在后台运行,当检测到剪贴板内容变化时,会记录剪贴板内容并显示通知提示。支持文本和图片媒体的记录。
## 功能特点
- 实时监控剪贴板变化
- 自动记录剪贴板历史内容
- 支持图片媒体的记录和保存
- 系统托盘图标,最小化运行
- 可暂停/继续监控
- 查看历史记录
- 支持开机自启动
## 系统要求
- Windows 64位操作系统
- Python 3.11或更高版本
- 必要的Python库pyperclip, pystray, pillow (PIL), pywin32
## 安装步骤
1. 确保已安装Python 3.11或更高版本
2. 双击运行`start_clipboard_monitor.bat`,脚本会自动检查并安装必要的库
## 使用方法
### 启动程序
双击运行`start_clipboard_monitor.bat`文件即可启动剪贴板监控程序。程序启动后会在系统托盘显示图标。
### 设置开机自启动
如果希望程序在Windows启动时自动运行请双击运行`setup_autostart.bat`文件它会在Windows的启动文件夹中创建必要的快捷方式。
### 使用界面
程序启动后会在系统托盘区域显示一个图标,右键点击图标可以看到以下选项:
- **显示主窗口**:打开主界面,查看剪贴板历史记录
- **暂停/继续监控**:临时暂停或继续监控剪贴板
- **清空历史记录**:删除所有已记录的剪贴板历史
- **退出**:完全退出程序
### 主窗口
在主窗口中,您可以:
- 查看所有剪贴板历史记录
- 使用按钮暂停/继续监控
- 清空历史记录
- 退出程序
## 文件说明
- `clipboard_monitor.py`:主程序文件
- `start_clipboard_monitor.bat`:启动脚本
- `setup_autostart.bat`:设置开机自启动脚本
- `clipboard_monitor.log`:程序运行日志
- `clipboard_history.txt`:剪贴板历史记录
- `clipboard_media/`:保存剪贴板图片的文件夹
## 注意事项
1. 程序会在后台持续运行,如需完全退出,请通过系统托盘图标的"退出"选项或主窗口的"退出程序"按钮退出
2. 剪贴板历史记录保存在程序所在目录的`clipboard_history.txt`文件中
3. 剪贴板中的图片会保存在`clipboard_media`文件夹中,文本记录中会包含图片文件的引用
4. 如果遇到问题,可以查看`clipboard_monitor.log`日志文件了解详情
## 故障排除
如果程序无法正常启动或运行,请检查:
1. 确认Python版本是否为3.11或更高
2. 确认已安装所需的库pyperclip, pystray, pillow, pywin32
3. 查看`clipboard_monitor.log`日志文件,了解错误详情
4. 如果提示缺少库,可以手动安装:`pip install pyperclip pystray pillow pywin32`
## 隐私说明
本程序仅在本地运行,不会将任何数据发送到互联网。所有剪贴板内容仅保存在本地文件中。