Python+PyQt5開發(fā)一個智能鍵盤模擬輸入器(附整體源碼)
概述
在當今數(shù)字化辦公時代,自動化工具已經(jīng)成為提高工作效率的重要利器。今天我要向大家介紹一款基于PyQt5和pynput庫開發(fā)的智能鍵盤模擬輸入器——AQUA INPUT(測試可適用于學某通)。
開發(fā)背景
在日常工作和學習中,我們經(jīng)常會遇到需要重復輸入相同內(nèi)容的場景:
- 批量數(shù)據(jù)錄入
- 模板郵件發(fā)送
- 聊天機器人回復
- 測試數(shù)據(jù)填充
傳統(tǒng)的手工輸入方式不僅效率低下,而且容易出錯。AQUA INPUT應運而生,它通過模擬真實鍵盤輸入的方式,實現(xiàn)了文本內(nèi)容的自動化輸入,大大提升了工作效率。
技術(shù)棧
- GUI框架:PyQt5
- 輸入模擬:pynput.keyboard
- 界面風格:賽博朋克主題
- 多線程處理:QThread
- 動畫效果:QPropertyAnimation
功能特性
視覺設(shè)計

核心功能
| 功能模塊 | 圖標 | 描述 | 技術(shù)特點 |
|---|---|---|---|
| 數(shù)據(jù)輸入 | ?? | 支持多種數(shù)據(jù)導入方式 | 多編碼文件讀取、剪貼板集成 |
| 參數(shù)配置 | ?? | 靈活的輸入?yún)?shù)調(diào)整 | 滑塊控制、實時預覽 |
| 進度監(jiān)控 | ?? | 實時顯示執(zhí)行狀態(tài) | 多線程進度更新、統(tǒng)計信息 |
| 安全控制 | ?? | 緊急停止機制 | 線程安全中斷、狀態(tài)恢復 |
工作流程

界面展示
主界面設(shè)計



設(shè)計亮點:
- 分區(qū)明確:數(shù)據(jù)輸入、系統(tǒng)配置、執(zhí)行進度三大功能區(qū)
- 色彩協(xié)調(diào):深色背景搭配青色主題,保護視力
- 動態(tài)反饋:按鈕懸停效果、進度條動畫
- 響應式布局:自適應窗口大小變化
特色組件展示
1. 自定義標題欄
class CustomTitleBar(QWidget):
def __init__(self, parent):
super().__init__(parent)
# 實現(xiàn)無邊框窗口的自定義拖動功能
特點:
- 漸變背景效果
- 支持窗口拖動
- 自定義最小化/最大化/關(guān)閉按鈕
- 與主界面風格一致
2. 賽博風格控件
class CyberButton(QPushButton):
def __init__(self, text, parent=None):
super().__init__(text, parent)
# 實現(xiàn)動態(tài)發(fā)光效果
動畫效果:
- 鼠標懸停發(fā)光
- 漸變邊框
- 平滑過渡動畫
3. 倒計時窗口
功能:
- 全屏居中顯示
- 數(shù)字漸變效果
- 窗口置頂顯示
使用教程
第一步:數(shù)據(jù)準備
- 直接輸入:在主文本框中直接輸入需要自動輸入的內(nèi)容
- 剪貼板導入:點擊?? 剪貼板導入按鈕從系統(tǒng)剪貼板獲取內(nèi)容
- 文件加載:點擊?? 文件加載按鈕從文本文件導入數(shù)據(jù)
提示:支持多種文件編碼格式(UTF-8、GBK、GB2312等)
第二步:參數(shù)配置
| 參數(shù)項 | 推薦設(shè)置 | 說明 |
|---|---|---|
| 輸入速度 | 0.05-0.1秒/字符 | 根據(jù)目標應用程序響應速度調(diào)整 |
| 啟動延遲 | 3-5秒 | 給予足夠時間定位光標 |
| 窗口置頂 | ? 開啟 | 避免窗口切換中斷輸入 |
| 倒計時界面 | ? 開啟 | 可視化倒計時提示 |
第三步:執(zhí)行輸入
- 定位光標:將輸入光標移動到目標應用程序的輸入框
- 啟動程序:點擊?? 啟動輸入序列按鈕
- 等待倒計時:程序顯示倒計時,此時不要操作鍵盤鼠標
- 自動輸入:程序開始自動輸入文本內(nèi)容
- 完成提示:輸入完成后顯示狀態(tài)提示
第四步:異常處理
- 緊急停止:任何時候點擊?? 緊急停止按鈕可立即中斷輸入
- 狀態(tài)恢復:程序中斷后會自動恢復控件狀態(tài)
- 進度保存:中斷時已輸入的進度會保留在進度條中
高級技巧

代碼深度解析
1. 架構(gòu)設(shè)計
# 核心類關(guān)系圖
classDiagram
class MainWindow {
-QTextEdit text_edit
-TypeThread thread
-QProgressBar progress_bar
+start_typing()
+stop_typing()
}
class TypeThread {
-str text
-float speed
+run()
+stop()
}
class CustomTitleBar {
-QPushButton close_btn
+mousePressEvent()
+mouseMoveEvent()
}
MainWindow --> TypeThread
MainWindow --> CustomTitleBar
2. 多線程輸入核心
class TypeThread(QThread):
update_signal = pyqtSignal(str)
finished_signal = pyqtSignal()
def run(self):
keyboard = Controller()
total_chars = len(self.text)
for i, char in enumerate(self.text):
if not self._is_running:
break
keyboard.type(char)
progress = int((i + 1) / total_chars * 100)
self.progress_signal.emit(progress)
if self.speed > 0:
time.sleep(self.speed)
關(guān)鍵技術(shù)點:
- 線程安全:使用標志位控制線程退出
- 信號通信:通過pyqtSignal實現(xiàn)線程與UI通信
- 精確控制:可調(diào)節(jié)的輸入速度參數(shù)
- 進度反饋:實時更新進度條和狀態(tài)信息
3. 界面主題系統(tǒng)
def set_aqua_theme(self):
"""設(shè)置青色賽博朋克主題"""
self.setStyleSheet("""
QMainWindow {
background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
stop:0 #1a1a1a, stop:0.5 #2a2a2a, stop:1 #1a1a1a);
color: #00ffff;
border: 1px solid #00ffff;
border-radius: 8px;
}
""")
樣式特點:
- CSS-like語法:使用Qt樣式表實現(xiàn)復雜效果
- 漸變背景:線性漸變營造科技感
- 圓角邊框:現(xiàn)代化界面設(shè)計
- 色彩系統(tǒng):統(tǒng)一的青色主題色
4. 資源管理機制
def get_resource_path(relative_path):
"""獲取資源的絕對路徑,兼容開發(fā)環(huán)境和打包后環(huán)境"""
try:
base_path = sys._MEIPASS
except Exception:
base_path = os.path.abspath(".")
# 多路徑查找策略
path = os.path.join(base_path, relative_path)
if not os.path.exists(path):
# 嘗試在當前目錄和上級目錄查找
current_dir_path = os.path.join(os.path.abspath("."), relative_path)
if os.path.exists(current_dir_path):
return current_dir_path
return path
兼容性設(shè)計:
- 打包支持:同時支持開發(fā)環(huán)境和PyInstaller打包
- 多路徑查找:自動在多個位置查找資源文件
- 優(yōu)雅降級:資源缺失時不影響主要功能
5. 動畫效果實現(xiàn)
class CyberButton(QPushButton):
def __init__(self, text, parent=None):
super().__init__(text, parent)
self._glow = 0
self.setMouseTracking(True)
def animate_glow(self, target):
animation = QPropertyAnimation(self, b"glow")
animation.setDuration(300)
animation.setStartValue(self._glow)
animation.setEndValue(target)
animation.setEasingCurve(QEasingCurve.OutCubic)
animation.start()
動畫技術(shù):
- 屬性動畫:使用QPropertyAnimation實現(xiàn)平滑過渡
- 事件響應:鼠標懸停觸發(fā)動畫效果
- 性能優(yōu)化:使用合適的動畫時長和緩動函數(shù)
源碼下載
import os
import sys
from PyQt5.QtWidgets import (QApplication, QMainWindow, QVBoxLayout, QHBoxLayout,
QPushButton, QLabel, QTextEdit, QWidget, QFileDialog,
QMessageBox, QSpinBox, QCheckBox, QDialog, QDoubleSpinBox,
QGroupBox, QProgressBar, QScrollArea,QSizePolicy, QSlider)
from PyQt5.QtCore import Qt, QThread, pyqtSignal, QTimer, QPropertyAnimation, QEasingCurve
from PyQt5.QtGui import QFont, QIcon, QPalette, QColor, QLinearGradient, QPainter
from PyQt5.QtCore import pyqtProperty
from pynput.keyboard import Controller
import time
def get_resource_path(relative_path):
"""獲取資源的絕對路徑,兼容開發(fā)環(huán)境和打包后環(huán)境"""
try:
base_path = sys._MEIPASS
except Exception:
base_path = os.path.abspath(".")
path = os.path.join(base_path, relative_path)
# 如果找不到文件,嘗試在多個位置查找
if not os.path.exists(path):
# 嘗試在當前目錄查找
current_dir_path = os.path.join(os.path.abspath("."), relative_path)
if os.path.exists(current_dir_path):
return current_dir_path
# 嘗試在上級目錄查找
parent_dir_path = os.path.join(os.path.abspath(".."), relative_path)
if os.path.exists(parent_dir_path):
return parent_dir_path
return path
class TitleBarButton(QPushButton):
def __init__(self, text, parent=None):
super().__init__(text, parent)
self.setFixedSize(30, 25)
self.setStyleSheet("""
QPushButton {
background-color: rgba(80, 80, 80, 200);
border: 1px solid #00ffff;
border-radius: 3px;
color: #00ffff;
font-size: 10px;
font-weight: bold;
}
QPushButton:hover {
background-color: rgba(100, 100, 100, 200);
}
QPushButton:pressed {
background-color: rgba(120, 120, 120, 200);
}
""")
class CloseButton(TitleBarButton):
def __init__(self, parent=None):
super().__init__("?", parent)
self.setStyleSheet("""
QPushButton {
background-color: rgba(80, 80, 80, 200);
border: 1px solid #00ffff;
border-radius: 3px;
color: #00ffff;
font-size: 12px;
font-weight: bold;
}
QPushButton:hover {
background-color: rgba(255, 0, 0, 100);
border: 1px solid #ff0000;
color: #ffffff;
}
QPushButton:pressed {
background-color: rgba(200, 0, 0, 150);
}
""")
class MinimizeButton(TitleBarButton):
def __init__(self, parent=None):
super().__init__("—", parent)
class MaximizeButton(TitleBarButton):
def __init__(self, parent=None):
super().__init__("□", parent)
class CyberLabel(QLabel):
def __init__(self, text, parent=None):
super().__init__(text, parent)
self._glow_intensity = 0
self.glow_animation = QPropertyAnimation(self, b"glow_intensity")
self.glow_animation.setDuration(2000)
self.glow_animation.setLoopCount(-1)
self.glow_animation.setStartValue(0)
self.glow_animation.setEndValue(100)
self.glow_animation.start()
def get_glow_intensity(self):
return self._glow_intensity
def set_glow_intensity(self, value):
self._glow_intensity = value
self.update()
glow_intensity = pyqtProperty(int, get_glow_intensity, set_glow_intensity)
def paintEvent(self, event):
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing)
# 青色主題
gradient = QLinearGradient(0, 0, self.width(), 0)
base_color = QColor(0, 255, 255) # 青色
glow_color = QColor(0, 200, 200, 150 + self._glow_intensity)
gradient.setColorAt(0, base_color)
gradient.setColorAt(0.5, glow_color)
gradient.setColorAt(1, base_color)
painter.setPen(QColor(0, 255, 255))
painter.setFont(self.font())
painter.drawText(self.rect(), Qt.AlignCenter, self.text())
class CyberButton(QPushButton):
def __init__(self, text, parent=None):
super().__init__(text, parent)
self._glow = 0
self.setMouseTracking(True)
def enterEvent(self, event):
self.animate_glow(50)
super().enterEvent(event)
def leaveEvent(self, event):
self.animate_glow(0)
super().leaveEvent(event)
def animate_glow(self, target):
animation = QPropertyAnimation(self, b"glow")
animation.setDuration(300)
animation.setStartValue(self._glow)
animation.setEndValue(target)
animation.setEasingCurve(QEasingCurve.OutCubic)
animation.start()
def get_glow(self):
return self._glow
def set_glow(self, value):
self._glow = value
self.update()
glow = pyqtProperty(int, get_glow, set_glow)
def paintEvent(self, event):
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing)
# 灰色背景,青色邊框
bg_color = QColor(60, 60, 60, 220) # 深灰色
painter.fillRect(self.rect(), bg_color)
# 青色邊框
border_color = QColor(0, 255, 255, 60 + self._glow)
painter.setPen(border_color)
painter.drawRect(1, 1, self.width()-2, self.height()-2)
# 青色文字
text_color = QColor(0, 255, 255)
painter.setPen(text_color)
painter.setFont(self.font())
painter.drawText(self.rect(), Qt.AlignCenter, self.text())
class CyberSpinBox(QSpinBox):
def __init__(self, parent=None):
super().__init__(parent)
self.setStyleSheet("""
QSpinBox {
background-color: rgba(80, 80, 80, 200);
border: 1px solid #00ffff;
border-radius: 4px;
color: #00ffff;
padding: 5px;
font-size: 12px;
selection-background-color: #00ffff;
selection-color: #000;
}
QSpinBox:focus {
border: 1px solid #00cccc;
}
QSpinBox::up-button, QSpinBox::down-button {
background-color: #00ffff;
border: none;
width: 15px;
border-radius: 2px;
}
QSpinBox::up-button:hover, QSpinBox::down-button:hover {
background-color: #00cccc;
}
QSpinBox::up-arrow, QSpinBox::down-arrow {
width: 8px;
height: 8px;
color: #000;
}
""")
class CyberDoubleSpinBox(QDoubleSpinBox):
def __init__(self, parent=None):
super().__init__(parent)
self.setStyleSheet("""
QDoubleSpinBox {
background-color: rgba(80, 80, 80, 200);
border: 1px solid #00ffff;
border-radius: 4px;
color: #00ffff;
padding: 5px;
font-size: 12px;
selection-background-color: #00ffff;
selection-color: #000;
}
QDoubleSpinBox:focus {
border: 1px solid #00cccc;
}
QDoubleSpinBox::up-button, QDoubleSpinBox::down-button {
background-color: #00ffff;
border: none;
width: 15px;
border-radius: 2px;
}
QDoubleSpinBox::up-button:hover, QDoubleSpinBox::down-button:hover {
background-color: #00cccc;
}
QDoubleSpinBox::up-arrow, QDoubleSpinBox::down-arrow {
width: 8px;
height: 8px;
color: #000;
}
""")
class CyberSlider(QSlider):
def __init__(self, orientation=Qt.Horizontal, parent=None):
super().__init__(orientation, parent)
self.setStyleSheet("""
QSlider::groove:horizontal {
border: 1px solid #00ffff;
height: 8px;
background: qlineargradient(x1:0, y1:0, x2:1, y2:0,
stop:0 #1a1a1a, stop:0.5 #2a2a2a, stop:1 #1a1a1a);
border-radius: 4px;
}
QSlider::handle:horizontal {
background: qlineargradient(x1:0, y1:0, x2:1, y2:0,
stop:0 #00ffff, stop:0.5 #00cccc, stop:1 #00ffff);
border: 1px solid #00ffff;
width: 18px;
margin: -5px 0;
border-radius: 9px;
}
QSlider::handle:horizontal:hover {
background: qlineargradient(x1:0, y1:0, x2:1, y2:0,
stop:0 #00cccc, stop:0.5 #00aaaa, stop:1 #00cccc);
border: 1px solid #00cccc;
}
QSlider::sub-page:horizontal {
background: qlineargradient(x1:0, y1:0, x2:1, y2:0,
stop:0 #00ffff, stop:0.5 #00cccc, stop:1 #00ffff);
border-radius: 4px;
}
""")
class CountdownWindow(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("倒計時")
self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint)
self.setStyleSheet("""
background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
stop:0 #2a2a2a, stop:0.5 #3a3a3a, stop:1 #2a2a2a);
border: 2px solid #00ffff;
border-radius: 10px;
""")
layout = QVBoxLayout()
self.countdown_label = QLabel("5")
self.countdown_label.setAlignment(Qt.AlignCenter)
self.countdown_label.setStyleSheet("""
color: #00ffff;
font-size: 72px;
font-weight: bold;
font-family: 'Arial';
background: transparent;
""")
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()) // 2
y = (screen.height() - self.height()) // 2
self.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()
status_signal = pyqtSignal(str)
progress_signal = pyqtSignal(int)
def __init__(self, text, speed=0.05):
super().__init__()
self.text = text
self.speed = speed
self._is_running = True
def run(self):
keyboard = Controller()
total_chars = len(self.text)
for i, char in enumerate(self.text):
if not self._is_running:
break
keyboard.type(char)
progress = int((i + 1) / total_chars * 100)
self.progress_signal.emit(progress)
status_text = f"正在輸入: {i+1}/{total_chars} 字符"
self.status_signal.emit(status_text)
if self.speed > 0:
time.sleep(self.speed)
self.finished_signal.emit()
def stop(self):
self._is_running = False
class CyberTextEdit(QTextEdit):
def __init__(self, parent=None):
super().__init__(parent)
self.setStyleSheet("""
QTextEdit {
background-color: rgba(80, 80, 80, 200);
border: 2px solid #00ffff;
border-radius: 8px;
color: #00ffff;
font-size: 14px;
padding: 10px;
selection-background-color: #00ffff;
selection-color: #000;
}
QTextEdit:focus {
border: 2px solid #00cccc;
}
""")
class CyberCheckBox(QCheckBox):
def __init__(self, text, parent=None):
super().__init__(text, parent)
self.setStyleSheet("""
QCheckBox {
color: #00ffff;
font-size: 12px;
spacing: 5px;
}
QCheckBox::indicator {
width: 15px;
height: 15px;
border: 1px solid #00ffff;
background-color: rgba(80, 80, 80, 200);
}
QCheckBox::indicator:checked {
background-color: #00ffff;
}
QCheckBox::indicator:hover {
border: 1px solid #00cccc;
}
""")
項目結(jié)構(gòu)
AQUA-INPUT/
├── main.py # 主程序文件
├── icon.ico # 應用程序圖標
├── requirements.txt # 依賴包列表
├── README.md # 項目說明文檔
└── examples/ # 使用示例
├── sample_texts/ # 示例文本
└── config_examples/ # 配置示例
環(huán)境要求
# Python 3.7+ pip install PyQt5==5.15.7 pip install pynput==1.7.6
快速開始
克隆代碼:
git clone https://gitee.com/your-repo/aqua-input.git cd aqua-input
安裝依賴:
pip install -r requirements.txt
運行程序:
python main.py
打包發(fā)布
# 使用PyInstaller打包 pyinstaller --onefile --windowed --icon=icon.ico --name="AQUA_INPUT" main.py
總結(jié)與展望
技術(shù)總結(jié)
AQUA INPUT項目展示了多個重要的軟件開發(fā)技術(shù):
- 現(xiàn)代GUI開發(fā):使用PyQt5創(chuàng)建美觀的用戶界面
- 多線程編程:正確處理UI響應與后臺任務的協(xié)調(diào)
- 自動化控制:通過pynput實現(xiàn)系統(tǒng)級輸入模擬
- 項目打包:支持從開發(fā)到分發(fā)的完整流程
實際應用價值
- 辦公自動化:提升重復性文字工作的效率
- 軟件測試:自動化測試用例的數(shù)據(jù)輸入
- 游戲輔助:合法的游戲內(nèi)文本輸入(如聊天宏)
- 教育培訓:演示鍵盤輸入過程的工具
未來擴展方向

擴展功能規(guī)劃
- 腳本引擎:支持Python腳本控制輸入流程
- 插件系統(tǒng):允許第三方擴展功能
- 云配置同步:用戶配置的多設(shè)備同步
- 多語言支持:國際化界面和文檔
- 使用統(tǒng)計:用戶行為分析和優(yōu)化建議
到此這篇關(guān)于Python+PyQt5開發(fā)一個智能鍵盤模擬輸入器(附整體源碼)的文章就介紹到這了,更多相關(guān)Python鍵盤模擬輸入內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
pycharm+PyQt5+python最新開發(fā)環(huán)境配置(踩坑)
這篇文章主要介紹了pycharm+PyQt5+python最新開發(fā)環(huán)境配置(踩坑),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-02-02
如何通過Python的pyttsx3庫將文字轉(zhuǎn)為音頻
pyttsx3是一個開源的Python文本轉(zhuǎn)語音庫,可以將文本轉(zhuǎn)換為自然的人類語音,這篇文章主要介紹了如何通過Python的pyttsx3庫將文字轉(zhuǎn)為音頻,需要的朋友可以參考下2023-04-04

