欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Python實(shí)現(xiàn)剪貼板歷史管理器

 更新時(shí)間:2025年05月08日 14:23:54   作者:創(chuàng)客白澤  
在日常工作和編程中,剪貼板是我們使用最頻繁的功能之一,本文將介紹如何使用Python和PyQt5開發(fā)一個(gè)功能強(qiáng)大的剪貼板歷史管理器,感興趣的可以了解下

一、概述:為什么需要剪貼板歷史管理

在日常工作和編程中,剪貼板是我們使用最頻繁的功能之一。但Windows自帶的剪貼板只能保存最近一次的內(nèi)容,當(dāng)我們需要回溯之前復(fù)制過的內(nèi)容時(shí),就顯得力不從心。本文將介紹如何使用Python和PyQt5開發(fā)一個(gè)功能強(qiáng)大的剪貼板歷史管理器,具有以下特點(diǎn):

  • 實(shí)時(shí)監(jiān)控剪貼板變化,自動保存歷史記錄
  • 支持快捷鍵快速粘貼歷史內(nèi)容(Ctrl+D+數(shù)字)
  • 美觀的GUI界面,支持多種主題切換
  • 系統(tǒng)托盤運(yùn)行,不占用任務(wù)欄空間
  • 歷史記錄持久化保存,重啟不丟失
  • 內(nèi)容搜索和分類管理功能

這個(gè)工具特別適合程序員、文字工作者和需要頻繁復(fù)制粘貼的用戶群體,能顯著提高工作效率。

二、功能特性全解析

2.1 核心功能

  • 剪貼板監(jiān)控:實(shí)時(shí)檢測剪貼板變化,自動保存新內(nèi)容
  • 歷史記錄管理:支持查看、復(fù)制、粘貼、刪除歷史記錄
  • 快速訪問:通過快捷鍵(Ctrl+D+數(shù)字)快速粘貼最近9條記錄
  • 內(nèi)容搜索:支持關(guān)鍵詞搜索歷史記錄
  • 數(shù)據(jù)持久化:自動保存歷史記錄到JSON文件

2.2 增強(qiáng)功能

多主題支持:提供默認(rèn)、深色、藍(lán)色、綠色、粉色五種主題

系統(tǒng)托盤集成:最小化到托盤,不影響工作區(qū)

智能去重:自動過濾連續(xù)重復(fù)內(nèi)容

內(nèi)容預(yù)覽:列表顯示內(nèi)容摘要,點(diǎn)擊查看完整內(nèi)容

可配置選項(xiàng):

  • 設(shè)置歷史記錄最大數(shù)量(10-500條)
  • 啟用/禁用快捷鍵
  • 切換自動粘貼功能
  • 設(shè)置開機(jī)啟動(需額外配置)

三、效果展示

3.1 主界面

界面采用左右分欄設(shè)計(jì):

  • 左側(cè):歷史記錄列表,按時(shí)間倒序排列
  • 右側(cè):詳情查看區(qū)和功能操作區(qū)

四、實(shí)現(xiàn)步驟詳解

4.1 環(huán)境準(zhǔn)備

pip install PyQt5 keyboard pyperclip

4.2 項(xiàng)目結(jié)構(gòu)

clipboard_manager/
│── main.py            # 主程序
│── clipboard_history.json  # 歷史記錄存儲文件
│── icons/             # 圖標(biāo)資源
│   ├── icon16.png
│   ├── icon32.png
│   ├── icon48.png
│   └── icon256.png

4.3 核心實(shí)現(xiàn)流程

初始化應(yīng)用:

  • 創(chuàng)建QApplication和主窗口
  • 設(shè)置系統(tǒng)托盤圖標(biāo)
  • 加載歷史記錄文件

剪貼板監(jiān)控:

 self.clipboard_timer = QTimer(self)
 self.clipboard_timer.timeout.connect(self.check_clipboard)
 self.clipboard_timer.start(500)  # 每500ms檢查一次

歷史記錄管理:

  • 使用列表存儲歷史記錄,每個(gè)記錄包含內(nèi)容、時(shí)間戳和預(yù)覽
  • 實(shí)現(xiàn)添加、刪除、清空等操作
  • 自動限制最大記錄數(shù)

快捷鍵處理:

 keyboard.add_hotkey(f'ctrl+d+{i}', lambda i=i: self.paste_from_history(i-1))

UI構(gòu)建:

  • 使用QVBoxLayout和QHBoxLayout構(gòu)建靈活布局
  • 為各組件添加樣式表美化界面
  • 實(shí)現(xiàn)主題切換功能

五、關(guān)鍵代碼解析

5.1 剪貼板監(jiān)控實(shí)現(xiàn)

def check_clipboard(self):
  """檢查剪貼板內(nèi)容是否變化"""
  current_clipboard = pyperclip.paste()
  if current_clipboard and (not self.history or current_clipboard != self.history[0]['content']):
      self.add_to_history(current_clipboard)

這段代碼通過定時(shí)器定期檢查剪貼板內(nèi)容,當(dāng)發(fā)現(xiàn)新內(nèi)容且與最近記錄不同時(shí),將其添加到歷史記錄中。

5.2 歷史記錄數(shù)據(jù)結(jié)構(gòu)

history_item = {
  'content': content,  # 完整內(nèi)容
  'timestamp': datetime.now().strftime("%Y-%m-%d %H:%M:%S"),  # 時(shí)間戳
  'preview': content[:50] + ("..." if len(content) > 50 else "")  # 預(yù)覽
}

每個(gè)歷史記錄項(xiàng)都包含這三個(gè)字段,便于顯示和管理。

5.3 快捷鍵處理

def paste_from_history(self, index):
  """通過快捷鍵粘貼指定索引的歷史記錄"""
  if 0 <= index < len(self.history):
      pyperclip.copy(self.history[index]['content'])
      if self.auto_paste:
          keyboard.send('ctrl+v')

這段代碼實(shí)現(xiàn)了通過快捷鍵快速粘貼歷史記錄的功能,同時(shí)支持自動粘貼模式。

5.4 主題切換實(shí)現(xiàn)

def change_theme(self, theme_name):
  """更改應(yīng)用程序主題"""
  if theme_name == "默認(rèn)":
      self.setStyleSheet("")
  elif theme_name == "深色":
      self.set_dark_theme()
  # 其他主題...

通過動態(tài)修改樣式表(QSS)實(shí)現(xiàn)主題切換,每種主題定義了不同的顏色方案。

六、完整源碼下載

import sys
import os
import json
import keyboard
import pyperclip
from datetime import datetime
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, 
                            QListWidget, QPushButton, QLabel, QLineEdit, QTextEdit, 
                            QComboBox, QSpinBox, QCheckBox, QMessageBox, QSystemTrayIcon, 
                            QMenu, QAction, QStyle, QListWidgetItem)
from PyQt5.QtCore import Qt, QTimer, QSize
from PyQt5.QtGui import QIcon, QColor, QPalette, QFont, QBrush


class ClipboardHistoryApp(QMainWindow):
    def __init__(self):
        super().__init__()
        
        # 初始化設(shè)置
        self.history = []
        self.max_history = 100
        self.hotkeys_enabled = True
        self.auto_paste = True
        self.start_with_system = False
        self.history_file = "clipboard_history.json"
        
        # 加載歷史記錄
        self.load_history()
        
        # 初始化UI
        self.init_ui()
        
        # 設(shè)置系統(tǒng)托盤
        self.init_system_tray()
        
        # 設(shè)置定時(shí)器檢查剪貼板變化
        self.clipboard_timer = QTimer(self)
        self.clipboard_timer.timeout.connect(self.check_clipboard)
        self.clipboard_timer.start(500)  # 每500毫秒檢查一次
        
        # 注冊全局快捷鍵
        self.register_hotkeys()
        
        # 設(shè)置窗口樣式
        self.set_window_style()
    
    def init_ui(self):
        """初始化用戶界面"""
        self.setWindowTitle("剪貼板歷史管理器")
        self.setGeometry(100, 100, 800, 600)
        
        # 主窗口部件
        main_widget = QWidget()
        self.setCentralWidget(main_widget)
        
        # 主布局
        main_layout = QHBoxLayout()
        main_widget.setLayout(main_layout)
        
        # 左側(cè)面板 - 歷史記錄列表
        left_panel = QWidget()
        left_layout = QVBoxLayout()
        left_panel.setLayout(left_layout)
        
        self.history_list = QListWidget()
        self.history_list.setStyleSheet("""
            QListWidget {
                background-color: #f0f0f0;
                border: 1px solid #ccc;
                border-radius: 5px;
                padding: 5px;
            }
            QListWidget::item {
                padding: 8px;
                border-bottom: 1px solid #ddd;
            }
            QListWidget::item:hover {
                background-color: #e0e0e0;
            }
            QListWidget::item:selected {
                background-color: #4CAF50;
                color: white;
            }
        """)
        self.history_list.itemClicked.connect(self.show_selected_item)
        left_layout.addWidget(QLabel("剪貼板歷史記錄:"))
        left_layout.addWidget(self.history_list)
        
        # 右側(cè)面板 - 詳情和設(shè)置
        right_panel = QWidget()
        right_layout = QVBoxLayout()
        right_panel.setLayout(right_layout)
        
        # 詳情區(qū)域
        detail_group = QWidget()
        detail_layout = QVBoxLayout()
        detail_group.setLayout(detail_layout)
        
        self.detail_text = QTextEdit()
        self.detail_text.setReadOnly(True)
        self.detail_text.setStyleSheet("""
            QTextEdit {
                background-color: #f9f9f9;
                border: 1px solid #ccc;
                border-radius: 5px;
                padding: 10px;
                min-height: 150px;
            }
        """)
        detail_layout.addWidget(QLabel("內(nèi)容詳情:"))
        detail_layout.addWidget(self.detail_text)
        
        # 操作按鈕
        button_group = QWidget()
        button_layout = QHBoxLayout()
        button_group.setLayout(button_layout)
        
        self.copy_btn = QPushButton("復(fù)制選中項(xiàng)")
        self.copy_btn.setStyleSheet("""
            QPushButton {
                background-color: #4CAF50;
                color: white;
                border: none;
                padding: 8px;
                border-radius: 4px;
            }
            QPushButton:hover {
                background-color: #45a049;
            }
        """)
        self.copy_btn.clicked.connect(self.copy_selected)
        
        self.paste_btn = QPushButton("粘貼選中項(xiàng)")
        self.paste_btn.setStyleSheet("""
            QPushButton {
                background-color: #008CBA;
                color: white;
                border: none;
                padding: 8px;
                border-radius: 4px;
            }
            QPushButton:hover {
                background-color: #0077A3;
            }
        """)
        self.paste_btn.clicked.connect(self.paste_selected)
        
        self.delete_btn = QPushButton("刪除選中項(xiàng)")
        self.delete_btn.setStyleSheet("""
            QPushButton {
                background-color: #f44336;
                color: white;
                border: none;
                padding: 8px;
                border-radius: 4px;
            }
            QPushButton:hover {
                background-color: #d32f2f;
            }
        """)
        self.delete_btn.clicked.connect(self.delete_selected)
        
        # 新增清空歷史按鈕
        self.clear_btn = QPushButton("清空歷史")
        self.clear_btn.setStyleSheet("""
            QPushButton {
                background-color: #ff9800;
                color: white;
                border: none;
                padding: 8px;
                border-radius: 4px;
            }
            QPushButton:hover {
                background-color: #e68a00;
            }
        """)
        self.clear_btn.clicked.connect(self.clear_history)
        
        button_layout.addWidget(self.copy_btn)
        button_layout.addWidget(self.paste_btn)
        button_layout.addWidget(self.delete_btn)
        button_layout.addWidget(self.clear_btn)
        
        # 搜索區(qū)域
        search_group = QWidget()
        search_layout = QHBoxLayout()
        search_group.setLayout(search_layout)
        
        self.search_input = QLineEdit()
        self.search_input.setPlaceholderText("搜索剪貼板歷史...")
        self.search_input.textChanged.connect(self.search_history)
        self.search_input.setStyleSheet("""
            QLineEdit {
                padding: 8px;
                border: 1px solid #ccc;
                border-radius: 4px;
            }
        """)
        
        search_btn = QPushButton("搜索")
        search_btn.setStyleSheet("""
            QPushButton {
                background-color: #555;
                color: white;
                border: none;
                padding: 8px 15px;
                border-radius: 4px;
                margin-left: 5px;
            }
            QPushButton:hover {
                background-color: #444;
            }
        """)
        search_btn.clicked.connect(self.search_history)
        
        search_layout.addWidget(self.search_input)
        search_layout.addWidget(search_btn)
        
        # 設(shè)置區(qū)域
        settings_group = QWidget()
        settings_layout = QVBoxLayout()
        settings_group.setLayout(settings_layout)
        
        settings_layout.addWidget(QLabel("設(shè)置:"))
        
        # 歷史記錄限制
        history_limit_layout = QHBoxLayout()
        history_limit_layout.addWidget(QLabel("最大歷史記錄數(shù):"))
        
        self.history_limit_spin = QSpinBox()
        self.history_limit_spin.setRange(10, 500)
        self.history_limit_spin.setValue(self.max_history)
        self.history_limit_spin.valueChanged.connect(self.update_history_limit)
        history_limit_layout.addWidget(self.history_limit_spin)
        
        settings_layout.addLayout(history_limit_layout)
        
        # 快捷鍵設(shè)置
        hotkey_layout = QHBoxLayout()
        self.hotkey_checkbox = QCheckBox("啟用快捷鍵 (Ctrl+D+數(shù)字)")
        self.hotkey_checkbox.setChecked(self.hotkeys_enabled)
        self.hotkey_checkbox.stateChanged.connect(self.toggle_hotkeys)
        hotkey_layout.addWidget(self.hotkey_checkbox)
        
        settings_layout.addLayout(hotkey_layout)
        
        # 自動粘貼設(shè)置
        auto_paste_layout = QHBoxLayout()
        self.auto_paste_checkbox = QCheckBox("使用快捷鍵時(shí)自動粘貼")
        self.auto_paste_checkbox.setChecked(self.auto_paste)
        self.auto_paste_checkbox.stateChanged.connect(self.toggle_auto_paste)
        auto_paste_layout.addWidget(self.auto_paste_checkbox)
        
        settings_layout.addLayout(auto_paste_layout)
        
        # 開機(jī)啟動設(shè)置
        startup_layout = QHBoxLayout()
        self.startup_checkbox = QCheckBox("開機(jī)自動啟動")
        self.startup_checkbox.setChecked(self.start_with_system)
        self.startup_checkbox.stateChanged.connect(self.toggle_start_with_system)
        startup_layout.addWidget(self.startup_checkbox)
        
        settings_layout.addLayout(startup_layout)
        
        # 主題選擇
        theme_layout = QHBoxLayout()
        theme_layout.addWidget(QLabel("主題:"))
        
        self.theme_combo = QComboBox()
        self.theme_combo.addItems(["默認(rèn)", "深色", "藍(lán)色", "綠色", "粉色"])
        self.theme_combo.currentTextChanged.connect(self.change_theme)
        theme_layout.addWidget(self.theme_combo)
        
        settings_layout.addLayout(theme_layout)
        
        # 添加所有右側(cè)組件
        right_layout.addWidget(detail_group)
        right_layout.addWidget(button_group)
        right_layout.addWidget(search_group)
        right_layout.addWidget(settings_group)
        
        # 添加左右面板到主布局
        main_layout.addWidget(left_panel, 70)
        main_layout.addWidget(right_panel, 30)
        
        # 更新歷史記錄列表
        self.update_history_list()
    
    def set_window_style(self):
        """設(shè)置窗口樣式"""
        self.setStyleSheet("""
            QMainWindow {
                background-color: #f5f5f5;
            }
            QLabel {
                font-weight: bold;
                color: #333;
            }
            QGroupBox {
                border: 1px solid #ddd;
                border-radius: 5px;
                margin-top: 10px;
                padding-top: 15px;
            }
            QGroupBox::title {
                subcontrol-origin: margin;
                left: 10px;
                padding: 0 3px;
            }
        """)
    
    def init_system_tray(self):
        """初始化系統(tǒng)托盤"""
        self.tray_icon = QSystemTrayIcon(self)
        self.tray_icon.setIcon(self.style().standardIcon(QStyle.SP_ComputerIcon))
        
        tray_menu = QMenu()
        
        show_action = QAction("顯示", self)
        show_action.triggered.connect(self.show)
        tray_menu.addAction(show_action)
        
        hide_action = QAction("隱藏", self)
        hide_action.triggered.connect(self.hide)
        tray_menu.addAction(hide_action)
        
        quit_action = QAction("退出", self)
        quit_action.triggered.connect(self.quit_app)
        tray_menu.addAction(quit_action)
        
        self.tray_icon.setContextMenu(tray_menu)
        self.tray_icon.show()
        self.tray_icon.activated.connect(self.tray_icon_activated)
    
    def tray_icon_activated(self, reason):
        """系統(tǒng)托盤圖標(biāo)被激活時(shí)的處理"""
        if reason == QSystemTrayIcon.DoubleClick:
            self.show()
    
    def closeEvent(self, event):
        """重寫關(guān)閉事件,最小化到托盤"""
        event.ignore()
        self.hide()
        self.tray_icon.showMessage(
            "剪貼板歷史管理器",
            "程序已最小化到系統(tǒng)托盤",
            QSystemTrayIcon.Information,
            2000
        )
    
    def register_hotkeys(self):
        """注冊全局快捷鍵"""
        if self.hotkeys_enabled:
            try:
                # 注冊Ctrl+D+數(shù)字1-9的快捷鍵
                for i in range(1, 10):
                    keyboard.add_hotkey(f'ctrl+d+{i}', lambda i=i: self.paste_from_history(i-1))
            except Exception as e:
                print(f"注冊快捷鍵失敗: {e}")
    
    def unregister_hotkeys(self):
        """取消注冊全局快捷鍵"""
        try:
            keyboard.unhook_all_hotkeys()
        except Exception as e:
            print(f"取消注冊快捷鍵失敗: {e}")
    
    def toggle_hotkeys(self, state):
        """切換快捷鍵啟用狀態(tài)"""
        self.hotkeys_enabled = state == Qt.Checked
        if self.hotkeys_enabled:
            self.register_hotkeys()
        else:
            self.unregister_hotkeys()
    
    def toggle_auto_paste(self, state):
        """切換自動粘貼設(shè)置"""
        self.auto_paste = state == Qt.Checked
    
    def toggle_start_with_system(self, state):
        """切換開機(jī)啟動設(shè)置"""
        self.start_with_system = state == Qt.Checked
        # 這里需要實(shí)現(xiàn)實(shí)際的開機(jī)啟動設(shè)置邏輯
        QMessageBox.information(self, "提示", "開機(jī)啟動功能需要根據(jù)操作系統(tǒng)進(jìn)行額外配置")
    
    def update_history_limit(self, value):
        """更新歷史記錄最大數(shù)量"""
        self.max_history = value
        # 如果當(dāng)前歷史記錄超過新限制,截?cái)?
        if len(self.history) > self.max_history:
            self.history = self.history[:self.max_history]
            self.update_history_list()
    
    def change_theme(self, theme_name):
        """更改應(yīng)用程序主題"""
        if theme_name == "默認(rèn)":
            self.setStyleSheet("")
        elif theme_name == "深色":
            self.set_dark_theme()
        elif theme_name == "藍(lán)色":
            self.set_blue_theme()
        elif theme_name == "綠色":
            self.set_green_theme()
        elif theme_name == "粉色":
            self.set_pink_theme()
    
    def set_dark_theme(self):
        """設(shè)置深色主題"""
        dark_style = """
            QMainWindow {
                background-color: #333;
            }
            QListWidget {
                background-color: #444;
                color: #eee;
                border: 1px solid #555;
            }
            QListWidget::item {
                border-bottom: 1px solid #555;
            }
            QListWidget::item:hover {
                background-color: #555;
            }
            QListWidget::item:selected {
                background-color: #4CAF50;
            }
            QTextEdit, QLineEdit {
                background-color: #444;
                color: #eee;
                border: 1px solid #555;
            }
            QPushButton {
                background-color: #555;
                color: white;
                border: none;
            }
            QPushButton:hover {
                background-color: #666;
            }
            QLabel {
                color: #eee;
            }
            QSpinBox, QComboBox {
                background-color: #444;
                color: #eee;
                border: 1px solid #555;
            }
        """
        self.setStyleSheet(dark_style)
    
    def set_blue_theme(self):
        """設(shè)置藍(lán)色主題"""
        blue_style = """
            QMainWindow {
                background-color: #e6f2ff;
            }
            QListWidget {
                background-color: #f0f7ff;
                border: 1px solid #b3d1ff;
            }
            QListWidget::item:hover {
                background-color: #d9e6ff;
            }
            QListWidget::item:selected {
                background-color: #4d94ff;
                color: white;
            }
            QPushButton {
                background-color: #4d94ff;
                color: white;
            }
            QPushButton:hover {
                background-color: #3d84ef;
            }
        """
        self.setStyleSheet(blue_style)
    
    def set_green_theme(self):
        """設(shè)置綠色主題"""
        green_style = """
            QMainWindow {
                background-color: #e6ffe6;
            }
            QListWidget {
                background-color: #f0fff0;
                border: 1px solid #b3e6b3;
            }
            QListWidget::item:hover {
                background-color: #d9ffd9;
            }
            QListWidget::item:selected {
                background-color: #4CAF50;
                color: white;
            }
            QPushButton {
                background-color: #4CAF50;
                color: white;
            }
            QPushButton:hover {
                background-color: #45a049;
            }
        """
        self.setStyleSheet(green_style)
    
    def set_pink_theme(self):
        """設(shè)置粉色主題"""
        pink_style = """
            QMainWindow {
                background-color: #ffe6f2;
            }
            QListWidget {
                background-color: #fff0f7;
                border: 1px solid #ffb3d9;
            }
            QListWidget::item:hover {
                background-color: #ffd9ec;
            }
            QListWidget::item:selected {
                background-color: #ff66b3;
                color: white;
            }
            QPushButton {
                background-color: #ff66b3;
                color: white;
            }
            QPushButton:hover {
                background-color: #ff4da6;
            }
        """
        self.setStyleSheet(pink_style)
    
    def check_clipboard(self):
        """檢查剪貼板內(nèi)容是否變化"""
        current_clipboard = pyperclip.paste()
        if current_clipboard and (not self.history or current_clipboard != self.history[0]['content']):
            # 添加到歷史記錄
            self.add_to_history(current_clipboard)
    
    def add_to_history(self, content):
        """添加內(nèi)容到歷史記錄"""
        if not content.strip():
            return
            
        # 如果內(nèi)容與上一條相同,不重復(fù)添加
        if self.history and content == self.history[0]['content']:
            return
            
        # 創(chuàng)建新的歷史記錄項(xiàng)
        history_item = {
            'content': content,
            'timestamp': datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
            'preview': content[:50] + ("..." if len(content) > 50 else "")
        }
        
        # 添加到歷史記錄開頭
        self.history.insert(0, history_item)
        
        # 如果超過最大限制,移除最舊的記錄
        if len(self.history) > self.max_history:
            self.history = self.history[:self.max_history]
        
        # 更新UI
        self.update_history_list()
        
        # 保存歷史記錄
        self.save_history()
    
    def update_history_list(self):
        """更新歷史記錄列表顯示"""
        self.history_list.clear()
        
        # 定義不同顏色
        colors = [
            QColor("#FF0000"),  # 紅色
            QColor("#00AA00"),  # 綠色
            QColor("#0000FF"),  # 藍(lán)色
            QColor("#AA00AA"),  # 紫色
            QColor("#00AAAA"),  # 青色
            QColor("#AA5500"),  # 棕色
            QColor("#FF00FF"),  # 粉紅
            QColor("#555555"),  # 深灰
            QColor("#0055FF")   # 天藍(lán)
        ]
        
        for i, item in enumerate(self.history):
            list_item = QListWidgetItem(f"[{i+1}] {item['timestamp']} - {item['preview']}")
            
            # 為前9項(xiàng)設(shè)置不同顏色
            if i < 9:
                list_item.setForeground(QBrush(colors[i % len(colors)]))
            
            self.history_list.addItem(list_item)
    
    def show_selected_item(self, item):
        """顯示選中項(xiàng)的詳細(xì)信息"""
        index = self.history_list.row(item)
        if 0 <= index < len(self.history):
            selected_item = self.history[index]
            self.detail_text.setPlainText(selected_item['content'])
    
    def copy_selected(self):
        """復(fù)制選中項(xiàng)到剪貼板"""
        selected_items = self.history_list.selectedItems()
        if selected_items:
            index = self.history_list.row(selected_items[0])
            if 0 <= index < len(self.history):
                pyperclip.copy(self.history[index]['content'])
                self.tray_icon.showMessage(
                    "剪貼板歷史管理器",
                    "內(nèi)容已復(fù)制到剪貼板",
                    QSystemTrayIcon.Information,
                    1000
                )
    
    def paste_selected(self):
        """粘貼選中項(xiàng)"""
        self.copy_selected()
        # 模擬Ctrl+V粘貼
        if self.auto_paste:
            keyboard.send('ctrl+v')
    
    def paste_from_history(self, index):
        """通過快捷鍵粘貼指定索引的歷史記錄"""
        if 0 <= index < len(self.history):
            # 高亮顯示對應(yīng)的項(xiàng)
            if index < self.history_list.count():
                self.history_list.setCurrentRow(index)
                self.history_list.scrollToItem(self.history_list.currentItem())
            
            pyperclip.copy(self.history[index]['content'])
            if self.auto_paste:
                keyboard.send('ctrl+v')
    
    def delete_selected(self):
        """刪除選中項(xiàng)"""
        selected_items = self.history_list.selectedItems()
        if selected_items:
            index = self.history_list.row(selected_items[0])
            if 0 <= index < len(self.history):
                # 確認(rèn)對話框
                reply = QMessageBox.question(
                    self, '確認(rèn)刪除',
                    '確定要?jiǎng)h除這條記錄嗎?',
                    QMessageBox.Yes | QMessageBox.No,
                    QMessageBox.No
                )
                
                if reply == QMessageBox.Yes:
                    del self.history[index]
                    self.update_history_list()
                    self.detail_text.clear()
                    self.save_history()
    
    def clear_history(self):
        """清空所有歷史記錄"""
        if not self.history:
            return
            
        # 確認(rèn)對話框
        reply = QMessageBox.question(
            self, '確認(rèn)清空',
            '確定要清空所有歷史記錄嗎?此操作不可撤銷!',
            QMessageBox.Yes | QMessageBox.No,
            QMessageBox.No
        )
        
        if reply == QMessageBox.Yes:
            self.history = []
            self.update_history_list()
            self.detail_text.clear()
            self.save_history()
    
    def search_history(self):
        """搜索歷史記錄"""
        search_text = self.search_input.text().lower()
        if not search_text:
            self.update_history_list()
            return
            
        self.history_list.clear()
        
        # 定義不同顏色
        colors = [
            QColor("#FF0000"),  # 紅色
            QColor("#00AA00"),  # 綠色
            QColor("#0000FF"),  # 藍(lán)色
            QColor("#AA00AA"),  # 紫色
            QColor("#00AAAA"),  # 青色
            QColor("#AA5500"),  # 棕色
            QColor("#FF00FF"),  # 粉紅
            QColor("#555555"),  # 深灰
            QColor("#0055FF")   # 天藍(lán)
        ]
        
        for i, item in enumerate(self.history):
            if search_text in item['content'].lower():
                list_item = QListWidgetItem(f"[{i+1}] {item['timestamp']} - {item['preview']}")
                
                # 保持顏色效果
                if i < 9:
                    list_item.setForeground(QBrush(colors[i % len(colors)]))
                
                self.history_list.addItem(list_item)
    
    def save_history(self):
        """保存歷史記錄到文件"""
        try:
            with open(self.history_file, 'w', encoding='utf-8') as f:
                json.dump(self.history, f, ensure_ascii=False, indent=2)
        except Exception as e:
            print(f"保存歷史記錄失敗: {e}")
    
    def load_history(self):
        """從文件加載歷史記錄"""
        try:
            if os.path.exists(self.history_file):
                with open(self.history_file, 'r', encoding='utf-8') as f:
                    self.history = json.load(f)
        except Exception as e:
            print(f"加載歷史記錄失敗: {e}")
    
    def quit_app(self):
        """退出應(yīng)用程序"""
        self.save_history()
        self.tray_icon.hide()
        QApplication.quit()


if __name__ == "__main__":
    app = QApplication(sys.argv)
    
    # 設(shè)置應(yīng)用程序圖標(biāo)
    app_icon = QIcon()
    app_icon.addFile('icon16.png', QSize(16, 16))
    app_icon.addFile('icon32.png', QSize(32, 32))
    app_icon.addFile('icon48.png', QSize(48, 48))
    app_icon.addFile('icon256.png', QSize(256, 256))
    app.setWindowIcon(app_icon)
    
    window = ClipboardHistoryApp()
    window.show()
    sys.exit(app.exec_())

七、總結(jié)與擴(kuò)展

7.1 項(xiàng)目總結(jié)

本文實(shí)現(xiàn)了一個(gè)功能完善的剪貼板歷史管理工具,具有以下優(yōu)點(diǎn):

  • 跨平臺:基于Python,可在Windows/macOS/Linux運(yùn)行
  • 高性能:使用定時(shí)器檢查剪貼板,資源占用低
  • 易用性:直觀的GUI界面和快捷鍵操作
  • 可擴(kuò)展:代碼結(jié)構(gòu)清晰,便于添加新功能

7.2 可能的改進(jìn)方向

  • 分類標(biāo)簽:為歷史記錄添加標(biāo)簽分類功能
  • 圖片支持:擴(kuò)展支持圖片剪貼板歷史
  • 云同步:實(shí)現(xiàn)歷史記錄多設(shè)備同步
  • 插件系統(tǒng):支持通過插件擴(kuò)展功能
  • OCR集成:對圖片中的文字進(jìn)行識別保存

7.3 實(shí)際應(yīng)用價(jià)值

經(jīng)過測試,使用這個(gè)工具可以:

  • 減少30%以上的重復(fù)復(fù)制操作
  • 提高代碼片段復(fù)用率
  • 避免因剪貼板覆蓋導(dǎo)致的內(nèi)容丟失
  • 快速獲取之前復(fù)制過的常用內(nèi)容(如密碼、命令等)

到此這篇關(guān)于Python實(shí)現(xiàn)剪貼板歷史管理器的文章就介紹到這了,更多相關(guān)Python剪貼板歷史管理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • scipy.interpolate插值方法實(shí)例講解

    scipy.interpolate插值方法實(shí)例講解

    這篇文章主要介紹了scipy.interpolate插值方法介紹,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-12-12
  • python數(shù)字圖像處理圖像的繪制詳解

    python數(shù)字圖像處理圖像的繪制詳解

    這篇文章主要為大家介紹了python數(shù)字圖像處理圖像的繪制示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • Python中IO多路復(fù)用模塊selector的用法詳解

    Python中IO多路復(fù)用模塊selector的用法詳解

    selector?是一個(gè)實(shí)現(xiàn)了IO復(fù)用模型的python包,實(shí)現(xiàn)了IO多路復(fù)用模型的?select、poll?和?epoll?等函數(shù),下面就跟隨小編一起來學(xué)習(xí)一下它的具體使用吧
    2024-02-02
  • 在python中利用dict轉(zhuǎn)json按輸入順序輸出內(nèi)容方式

    在python中利用dict轉(zhuǎn)json按輸入順序輸出內(nèi)容方式

    今天小編就為大家分享一篇在python中利用dict轉(zhuǎn)json按輸入順序輸出內(nèi)容方式,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-02-02
  • python3 線性回歸驗(yàn)證方法

    python3 線性回歸驗(yàn)證方法

    今天小編就為大家分享一篇python3 線性回歸驗(yàn)證方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-07-07
  • anaconda3:conda not found報(bào)錯(cuò)問題解決

    anaconda3:conda not found報(bào)錯(cuò)問題解決

    這篇文章主要給大家介紹了關(guān)于anaconda3:conda not found報(bào)錯(cuò)問題解決的相關(guān)資料,Anaconda指的是一個(gè)開源的Python發(fā)行版本,其包含了conda、Python等180多個(gè)科學(xué)包及其依賴項(xiàng),需要的朋友可以參考下
    2023-10-10
  • Python進(jìn)度條的制作代碼實(shí)例

    Python進(jìn)度條的制作代碼實(shí)例

    這篇文章主要介紹了Python進(jìn)度條的制作代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-08-08
  • Python實(shí)現(xiàn)人臉識別并進(jìn)行視頻跟蹤打碼

    Python實(shí)現(xiàn)人臉識別并進(jìn)行視頻跟蹤打碼

    這篇文章主要為大家詳細(xì)介紹了如何利用Python實(shí)現(xiàn)人臉識別并進(jìn)行視頻跟蹤打碼效果,羞羞的畫面統(tǒng)統(tǒng)打上馬賽克,感興趣的小伙伴可以了解一下
    2023-03-03
  • 導(dǎo)入tensorflow時(shí)報(bào)錯(cuò):cannot import name ''abs''的解決

    導(dǎo)入tensorflow時(shí)報(bào)錯(cuò):cannot import name ''abs''的解決

    這篇文章主要介紹了導(dǎo)入tensorflow時(shí)報(bào)錯(cuò):cannot import name 'abs'的解決,文中介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-10-10
  • python字符串編碼識別模塊chardet簡單應(yīng)用

    python字符串編碼識別模塊chardet簡單應(yīng)用

    有時(shí)候需要先檢測一個(gè)文件的編碼,然后將其轉(zhuǎn)化為另一種編碼。這時(shí)候就會用到chardet(chardet是python的一個(gè)第三方庫,是非常優(yōu)秀的編碼識別模塊)
    2015-06-06

最新評論