本文目录导读:

我来帮你写一个剪贴板历史管理脚本,这里提供几个不同复杂度的版本:
简单版本(命令行基础版)
#!/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文件中
扩展想法
- 添加加密存储敏感信息
- 支持图片剪贴板
- 添加快捷键支持
- 按时间范围筛选
- 分类管理剪贴板内容
这个脚本可以根据你的需求进行定制和扩展,需要我帮你添加其他功能吗?
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播