本文目录导读:

我来帮你写一个剪贴板历史管理脚本,这里提供几个不同复杂度的版本:
简单版本(命令行基础版)
#!/usr/bin/env python3
"""简单的剪贴板历史管理器"""
import pyperclip
import time
import json
import os
from pathlib import Path
class ClipboardHistory:
def __init__(self, history_file="clipboard_history.json"):
self.history_file = Path.home() / history_file
self.history = []
self.load_history()
def load_history(self):
"""加载历史记录"""
if self.history_file.exists():
with open(self.history_file, 'r') as f:
self.history = json.load(f)
def save_history(self):
"""保存历史记录"""
with open(self.history_file, 'w') as f:
json.dump(self.history, f, indent=2)
def watch(self):
"""监听剪贴板变化"""
last_text = pyperclip.paste()
print("监听剪贴板中... (Ctrl+C 退出)")
try:
while True:
current_text = pyperclip.paste()
if current_text != last_text and current_text.strip():
# 避免重复记录相同内容
if not self.history or self.history[0]["content"] != current_text:
self.history.insert(0, {
"content": current_text,
"timestamp": time.time()
})
# 限制历史记录数量,例如100条
if len(self.history) > 100:
self.history = self.history[:100]
self.save_history()
last_text = current_text
print(f"已保存: {current_text[:50]}...")
time.sleep(0.5) # 每0.5秒检查一次
except KeyboardInterrupt:
print("\n退出监听")
self.save_history()
def show_history(self):
"""显示历史记录"""
if not self.history:
print("暂无历史记录")
return
for i, item in enumerate(self.history, 1):
timestamp = time.strftime("%Y-%m-%d %H:%M",
time.localtime(item["timestamp"]))
content_preview = item["content"][:80] + "..." if len(item["content"]) > 80 else item["content"]
print(f"{i}. [{timestamp}] {content_preview}")
def copy_item(self, index):
"""复制指定历史项到剪贴板"""
if 0 < index <= len(self.history):
pyperclip.copy(self.history[index-1]["content"])
print(f"已复制第{index}项到剪贴板")
else:
print("无效的索引")
def main():
clip = ClipboardHistory()
# 这里可以根据命令行参数执行不同功能
import argparse
parser = argparse.ArgumentParser(description="剪贴板历史管理")
parser.add_argument("--watch", action="store_true", help="监听剪贴板")
parser.add_argument("--list", action="store_true", help="显示历史")
parser.add_argument("--copy", type=int, help="复制指定项")
args = parser.parse_args()
if args.watch:
clip.watch()
elif args.list:
clip.show_history()
elif args.copy:
clip.copy_item(args.copy)
else:
parser.print_help()
if __name__ == "__main__":
main()
GUI版本(带界面)
#!/usr/bin/env python3
"""带图形界面的剪贴板历史管理器"""
import tkinter as tk
from tkinter import ttk, messagebox
import pyperclip
import json
import time
from pathlib import Path
import threading
class ClipboardGUI:
def __init__(self, root):
self.root = root
self.root.title("剪贴板历史管理器")
self.root.geometry("600x400")
self.history_file = Path.home() / "clipboard_history.json"
self.history = []
self.running = False
self.setup_ui()
self.load_history()
def setup_ui(self):
"""设置界面"""
# 工具栏
toolbar = ttk.Frame(self.root)
toolbar.pack(pady=5)
ttk.Button(toolbar, text="开始监听", command=self.start_watching).pack(side=tk.LEFT, padx=5)
ttk.Button(toolbar, text="停止监听", command=self.stop_watching).pack(side=tk.LEFT, padx=5)
ttk.Button(toolbar, text="复制选中", command=self.copy_selected).pack(side=tk.LEFT, padx=5)
ttk.Button(toolbar, text="删除选中", command=self.delete_selected).pack(side=tk.LEFT, padx=5)
ttk.Button(toolbar, text="清空历史", command=self.clear_history).pack(side=tk.LEFT, padx=5)
# 搜索框
search_frame = ttk.Frame(self.root)
search_frame.pack(pady=5)
ttk.Label(search_frame, text="搜索:").pack(side=tk.LEFT)
self.search_var = tk.StringVar()
self.search_entry = ttk.Entry(search_frame, textvariable=self.search_var, width=40)
self.search_entry.pack(side=tk.LEFT, padx=5)
self.search_entry.bind('<KeyRelease>', self.filter_history)
# 列表
list_frame = ttk.Frame(self.root)
list_frame.pack(expand=True, fill=tk.BOTH, padx=10, pady=5)
self.tree = ttk.Treeview(list_frame, columns=("time", "content"), show="headings")
self.tree.heading("time", text="时间")
self.tree.heading("content", text="内容")
self.tree.column("time", width=150)
self.tree.column("content", width=400)
self.tree.pack(side=tk.LEFT, expand=True, fill=tk.BOTH)
scrollbar = ttk.Scrollbar(list_frame, orient=tk.VERTICAL, command=self.tree.yview)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
self.tree.configure(yscrollcommand=scrollbar.set)
# 双击复制
self.tree.bind("<Double-Button-1>", lambda e: self.copy_selected())
# 状态栏
self.status_var = tk.StringVar()
self.status_var.set("就绪")
status_bar = ttk.Label(self.root, textvariable=self.status_var, relief=tk.SUNKEN)
status_bar.pack(fill=tk.X)
def load_history(self):
"""加载历史记录"""
if self.history_file.exists():
with open(self.history_file, 'r') as f:
self.history = json.load(f)
self.refresh_list()
def save_history(self):
"""保存历史记录"""
with open(self.history_file, 'w') as f:
json.dump(self.history, f, indent=2, ensure_ascii=False)
def start_watching(self):
"""开始监听剪贴板"""
if self.running:
return
self.running = True
self.status_var.set("正在监听剪贴板...")
# 在后台线程中监听
self.watch_thread = threading.Thread(target=self.watch_clipboard, daemon=True)
self.watch_thread.start()
def stop_watching(self):
"""停止监听"""
self.running = False
self.status_var.set("已停止监听")
def watch_clipboard(self):
"""监听剪贴板变化"""
last_text = pyperclip.paste()
while self.running:
try:
current_text = pyperclip.paste()
if current_text != last_text and current_text.strip():
if not self.history or self.history[0]["content"] != current_text:
self.history.insert(0, {
"content": current_text,
"timestamp": time.time()
})
if len(self.history) > 100:
self.history = self.history[:100]
# 更新界面
self.root.after(0, self.refresh_list)
self.root.after(0, lambda: self.status_var.set("已捕获新内容"))
last_text = current_text
time.sleep(0.5)
except Exception as e:
print(f"监听出错: {e}")
def refresh_list(self):
"""刷新列表显示"""
# 清空当前列表
for i in self.tree.get_children():
self.tree.delete(i)
# 添加历史记录
search_text = self.search_var.get().lower()
for item in self.history:
content = item["content"]
if search_text and search_text not in content.lower():
continue
timestamp = time.strftime("%Y-%m-%d %H:%M:%S",
time.localtime(item["timestamp"]))
content_preview = content[:80] + "..." if len(content) > 80 else content
self.tree.insert("", 0, values=(timestamp, content_preview),
tags=(str(self.history.index(item)),))
self.save_history()
def filter_history(self, event=None):
"""过滤历史记录"""
self.refresh_list()
def copy_selected(self):
"""复制选中的内容"""
selection = self.tree.selection()
if not selection:
messagebox.showwarning("提示", "请先选择要复制的内容")
return
item = self.tree.item(selection[0])
index = int(item['tags'][0])
pyperclip.copy(self.history[index]["content"])
self.status_var.set("已复制到剪贴板")
def delete_selected(self):
"""删除选中的内容"""
selection = self.tree.selection()
if not selection:
messagebox.showwarning("提示", "请先选择要删除的内容")
return
if messagebox.askyesno("确认", "确定要删除选中项吗?"):
indexes = [int(self.tree.item(item)['tags'][0]) for item in selection]
for index in sorted(indexes, reverse=True):
del self.history[index]
self.refresh_list()
self.status_var.set(f"已删除{len(indexes)}项")
def clear_history(self):
"""清空历史记录"""
if messagebox.askyesno("确认", "确定要清空所有历史记录吗?"):
self.history = []
self.refresh_list()
self.status_var.set("历史记录已清空")
def main():
root = tk.Tk()
app = ClipboardGUI(root)
root.mainloop()
if __name__ == "__main__":
main()
安装依赖
# 安装所需模块 pip install pyperclip
使用说明
命令行版本使用:
# 启动监听 python clipboard_history.py --watch # 查看历史 python clipboard_history.py --list # 复制第3条记录 python clipboard_history.py --copy 3
GUI版本使用:
python clipboard_gui.py
功能特性
- 自动监听:实时捕获剪贴板变化
- 历史记录:保存最多100条剪贴板历史
- 搜索功能:GUI版本支持关键字搜索
- 快速复制:一键复制任意历史记录
- 持久化存储:历史记录保存在JSON文件中
扩展想法
- 添加加密存储敏感信息
- 支持图片剪贴板
- 添加快捷键支持
- 按时间范围筛选
- 分类管理剪贴板内容
这个脚本可以根据你的需求进行定制和扩展,需要我帮你添加其他功能吗?