📌 【黑科技】跳過網頁APP禁止粘貼限制:自動輸入鍵盤模擬工具
🌈 個人主頁:創客白澤 - CSDN博客
🔥 系列專欄:🐍《Python開源項目實戰》
💡 熱愛不止于代碼,熱情源自每一個靈感閃現的夜晚。愿以開源之火,點亮前行之路。
👍 如果覺得這篇文章有幫助,歡迎您一鍵三連,分享給更多人哦
🚀 概述:當自動化遇上可視化
在日常辦公和軟件開發中,我們經常需要處理大量重復的文本輸入工作。傳統的人工輸入不僅效率低下,還容易出錯。本文將介紹如何使用Python的PyQt5庫結合pynput鍵盤控制模塊,開發一款帶可視化倒計時提示的自動輸入工具。
本工具的特色在于:
- 采用現代化GUI界面設計
- 輸入前提供5秒可視化倒計時
- 支持從文件導入文本內容
- 實時狀態反饋機制
- 可自定義的窗口置頂功能
相比市面上其他自動化工具,我們的解決方案更加用戶友好且安全可控,特別適合以下場景:
- 自動化測試中的表單填充
- 批量數據錄入工作
- 演示時的自動輸入展示
- 需要延遲執行的文本輸入任務
🔍 功能全景圖
核心功能矩陣
功能模塊 | 技術實現方案 | 用戶體驗亮點 |
---|---|---|
文本編輯區 | QTextEdit控件 | 支持大文本流暢編輯 |
文件導入 | QFileDialog+多編碼處理 | 自動識別GBK/UTF-8編碼 |
倒計時顯示 | QDialog+QTimer | 居中大號紅色數字 |
鍵盤模擬 | pynput.keyboard.Controller | 非侵入式輸入模擬 |
狀態反饋 | QLabel動態更新 | 表情符號+顏色狀態指示 |
技術棧深度
- PyQt5:Qt框架的Python綁定,提供豐富的GUI組件
- pynput:底層輸入設備監控庫,支持跨平臺鍵盤控制
- QThread:實現后臺鍵入操作,避免界面凍結
- 信號槽機制:解耦UI與業務邏輯的關鍵設計
🎥 效果展示
主界面截圖
倒計時動效演示
🛠? 使用教程
環境準備
pip install pyqt5 pynput
四步操作指南
- 文本準備階段
- 直接在編輯區粘貼文本
- 或點擊"導入文件"按鈕選擇TXT文件
- 參數設置
- 勾選"窗口置頂"保持工具在最前端
- 檢查文本內容是否完整
- 執行輸入
- 點擊"開始輸入"觸發5秒倒計時
- 倒計時結束后自動開始鍵入
- 過程控制
- 隨時可點擊"停止輸入"中斷操作
- 狀態欄實時顯示當前進度
💡 專業提示:倒計時期間請將光標移動到目標輸入位置!
🔧 核心代碼解析
1. 倒計時窗口類設計
class CountdownWindow(QDialog):def __init__(self, parent=None):super().__init__(parent)self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint)self.setStyleSheet("background-color: black;")# 72pt超大紅色數字font = QFont("Arial", 72, QFont.Bold)self.countdown_label.setFont(font)
設計要點:
- 無邊框窗口確保專注度
- 黑色背景增強視覺對比
- 窗口置頂防止被遮擋
- 使用系統默認等寬字體保證數字顯示整齊
2. 鍵盤輸入線程
class TypeThread(QThread):def run(self):keyboard = Controller()for char in self.text:if not self._is_running: # 安全停止檢查點breakkeyboard.type(char) # 非阻塞式鍵入
關鍵技術:
- 繼承QThread實現多線程
- 每個字符獨立鍵入保證可控性
_is_running
標志位實現優雅中止
3. 狀態機管理
狀態轉換邏輯:
- 通過按鈕的enable/disable控制狀態流轉
- 統一的狀態欄消息格式:
[圖標] 狀態描述
- 異常狀態自動恢復機制
📥 源碼下載
from PyQt5.QtWidgets import (QApplication, QMainWindow, QVBoxLayout, QHBoxLayout, QPushButton, QLabel, QTextEdit, QWidget, QFileDialog, QMessageBox, QSpinBox, QCheckBox, QDialog)
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QTimer
from PyQt5.QtGui import QFont
from pynput.keyboard import Controller
import time
import sysclass CountdownWindow(QDialog):def __init__(self, parent=None):super().__init__(parent)self.setWindowTitle("倒計時")self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint)self.setStyleSheet("background-color: black;")layout = QVBoxLayout()self.countdown_label = QLabel("5")self.countdown_label.setAlignment(Qt.AlignCenter)self.countdown_label.setStyleSheet("color: red;")font = QFont("Arial", 72, QFont.Bold)self.countdown_label.setFont(font)layout.addWidget(self.countdown_label)self.setLayout(layout)# 設置窗口大小并居中self.resize(200, 200)self.move_to_center()def move_to_center(self):screen = QApplication.primaryScreen().geometry()x = (screen.width() - self.width()) // 2y = (screen.height() - self.height()) // 2self.move(x, y)def update_countdown(self, seconds):self.countdown_label.setText(str(seconds))if seconds <= 0:self.close()class TypeThread(QThread):update_signal = pyqtSignal(str)finished_signal = pyqtSignal()def __init__(self, text):super().__init__()self.text = textself._is_running = Truedef run(self):keyboard = Controller()for char in self.text:if not self._is_running:breakkeyboard.type(char)self.finished_signal.emit()def stop(self):self._is_running = Falseclass MainWindow(QMainWindow):def __init__(self):super().__init__()self.setWindowTitle("自動輸入工具")self.setGeometry(100, 100, 600, 400)# 初始化線程和倒計時窗口self.thread = Noneself.countdown_timer = QTimer()self.countdown_seconds = 5self.countdown_window = None# 創建主部件和布局main_widget = QWidget()main_layout = QVBoxLayout()# 標題title = QLabel("📋 自動輸入工具")title.setAlignment(Qt.AlignCenter)title.setStyleSheet("font-size: 20px; font-weight: bold;")main_layout.addWidget(title)# 說明info = QLabel("🔍 請將文本粘貼到下方或從文件導入")info.setAlignment(Qt.AlignCenter)main_layout.addWidget(info)# 文本編輯區self.text_edit = QTextEdit()self.text_edit.setPlaceholderText("📝 請在此粘貼要輸入的文本...")main_layout.addWidget(self.text_edit)# 控制區域control_layout = QHBoxLayout()# 窗口置頂復選框self.topmost_check = QCheckBox("📌 置頂")self.topmost_check.stateChanged.connect(self.toggle_topmost)control_layout.addWidget(self.topmost_check)# 按鈕btn_layout = QHBoxLayout()self.load_btn = QPushButton("📂 導入文件")self.load_btn.clicked.connect(self.load_from_file)btn_layout.addWidget(self.load_btn)self.start_btn = QPushButton("📝 開始輸入")self.start_btn.clicked.connect(self.start_typing)btn_layout.addWidget(self.start_btn)self.stop_btn = QPushButton("? 停止輸入")self.stop_btn.clicked.connect(self.stop_typing)self.stop_btn.setEnabled(False)btn_layout.addWidget(self.stop_btn)control_layout.addLayout(btn_layout)main_layout.addLayout(control_layout)# 狀態欄self.status_bar = QLabel("🟢 準備就緒")self.status_bar.setAlignment(Qt.AlignCenter)main_layout.addWidget(self.status_bar)main_widget.setLayout(main_layout)self.setCentralWidget(main_widget)# 樣式self.setStyleSheet("""QPushButton {padding: 8px;font-size: 14px;}QTextEdit {font-size: 14px;}""")# 連接倒計時定時器self.countdown_timer.timeout.connect(self.update_countdown)def toggle_topmost(self, state):if state == Qt.Checked:self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint)else:self.setWindowFlags(self.windowFlags() & ~Qt.WindowStaysOnTopHint)self.show()def start_countdown(self):self.countdown_seconds = 5self.countdown_window = CountdownWindow(self)self.countdown_window.show()self.countdown_timer.start(1000) # 1秒間隔self.status_bar.setText(f"? 倒計時: {self.countdown_seconds}秒...") # 更新狀態欄def update_countdown(self):self.countdown_seconds -= 1self.countdown_window.update_countdown(self.countdown_seconds)self.status_bar.setText(f"? 倒計時: {self.countdown_seconds}秒...") # 更新狀態欄if self.countdown_seconds <= 0:self.countdown_timer.stop()QTimer.singleShot(500, self.countdown_window.close) # 稍后關閉窗口self._start_typing_after_delay()def load_from_file(self):file_path, _ = QFileDialog.getOpenFileName(self, "📂 打開文本文件", "", "文本文件 (*.txt);;所有文件 (*)")if file_path:try:# 嘗試用UTF-8編碼打開,如果失敗則用GBK編碼try:with open(file_path, 'r', encoding='utf-8') as f:data = f.read()except UnicodeDecodeError:try:with open(file_path, 'r', encoding='gbk') as f:data = f.read()except UnicodeDecodeError:with open(file_path, 'r', encoding='utf-8', errors='replace') as f:data = f.read()self.text_edit.setPlainText(data)self.status_bar.setText(f"? 成功從 {file_path} 加載文本")except Exception as e:QMessageBox.critical(self, "? 錯誤", f"無法讀取文件: {str(e)}")self.status_bar.setText("? 文件加載失敗")def start_typing(self):if not self.text_edit.toPlainText().strip():QMessageBox.warning(self, "?? 警告", "請輸入或導入文本內容!")returnself.status_bar.setText("? 準備開始輸入...")self.start_btn.setEnabled(False)self.stop_btn.setEnabled(True)self.load_btn.setEnabled(False)# 開始倒計時self.start_countdown()def _start_typing_after_delay(self):text = self.text_edit.toPlainText()self.thread = TypeThread(text)self.thread.finished_signal.connect(self.typing_finished)self.thread.start()self.status_bar.setText("?? 正在輸入中...請勿操作鍵盤!")def stop_typing(self):if self.thread and self.thread.isRunning():self.thread.stop()self.thread.wait()# 如果倒計時還在進行也停止if self.countdown_timer.isActive():self.countdown_timer.stop()if self.countdown_window:self.countdown_window.close()self.typing_finished()self.status_bar.setText("🟡 輸入已停止")def typing_finished(self):self.start_btn.setEnabled(True)self.stop_btn.setEnabled(False)self.load_btn.setEnabled(True)self.status_bar.setText("? 輸入完成!")def closeEvent(self, event):# 停止所有正在進行的操作if self.thread and self.thread.isRunning():self.thread.stop()self.thread.wait()if self.countdown_timer.isActive():self.countdown_timer.stop()if self.countdown_window:self.countdown_window.close()event.accept()if __name__ == "__main__":app = QApplication(sys.argv)window = MainWindow()window.show()sys.exit(app.exec_())
文件結構:
auto-typer/
├── main.py # 主程序入口
├── requirements.txt # 依賴清單
└── README.md # 項目文檔
💡 開發心得
遇到的坑與解決方案
- 編碼問題:
- 現象:中文文本輸入亂碼
- 排查:發現pynput對Unicode支持需要特定處理
- 解決:在文本預處理階段統一轉為UTF-8
- 線程沖突:
- 現象:界面在輸入時卡頓
- 分析:GUI線程與輸入線程資源競爭
- 優化:采用信號槽進行跨線程通信
- 焦點丟失:
- 現象:倒計時后輸入位置錯誤
- 方案:增加倒計時結束前的焦點檢查提示
性能優化點
- 使用QTextEdit的逐行加載機制處理大文件
- 實現鍵入速度動態調節接口
- 添加輸入歷史記錄功能
🎯 未來擴展方向
- 企業級功能:
- 增加用戶權限管理系統
- 添加操作日志審計功能
- 支持LDAP集成認證
- AI增強:
- 集成OCR識別自動輸入
- 添加語音控制接口
- 智能表單識別填充
- 云化部署:
- 開發WebSocket遠程控制
- 實現移動端APP監控
- 增加多設備同步功能
📚 推薦學習資源
- 官方文檔:
- PyQt5權威指南
- pynput API參考
- 進階書籍:
- 《PyQt5快速開發與實戰》
- 《Python GUI設計之道》
- 相關項目:
- AutoHotkey開源社區
- Selenium自動化框架
?? 作者寄語:自動化工具開發的本質是"將重復勞動轉化為創造性工作"。希望本項目能幫助大家從繁瑣的鍵盤操作中解放出來,把寶貴的時間用在更有價值的事情上。如果覺得有用,請給個?鼓勵!
版權聲明:本文采用CC BY-NC-SA 4.0協議,轉載請注明出處。