使用PyQt和ADB操作雷电模拟器中QQ应用的完整指南
环境准备
1. 安装雷电模拟器
- 从雷电模拟器官网下载并安装最新版
- 安装完成后启动模拟器,完成初始设置
2. 安装必要软件
- 安装Python 3.8+
- 安装PyQt5:
pip install PyQt5
- 确保ADB工具可用(雷电模拟器自带ADB,路径通常为
雷电安装目录\adb.exe
)
3. 模拟器设置
- 打开雷电模拟器设置
- 进入"性能设置",建议分配至少2核CPU和2048MB内存
- 进入"其他设置",开启"Root权限"和"ADB调试"
- 安装QQ应用(可从应用中心或官网下载APK)
完整代码示例
import sys
import subprocess
import time
from PyQt5.QtWidgets import (QApplication, QWidget, QVBoxLayout,
QPushButton, QLabel, QComboBox, QLineEdit)
from PyQt5.QtGui import QPixmap
from PyQt5.QtCore import Qt, QSize
class QQController(QWidget):
def __init__(self):
super().__init__()
# QQ应用信息
self.qq_package = "com.tencent.mobileqq"
self.qq_activity = "com.tencent.mobileqq.activity.SplashActivity"
# 雷电模拟器默认ADB端口
self.leidian_port = "5555"
self.adb_path = r"C:\leidian\LDPlayer\adb.exe" # 修改为你的雷电ADB路径
self.initUI()
def initUI(self):
self.setWindowTitle('雷电模拟器QQ控制器')
self.setMinimumSize(QSize(800, 600))
layout = QVBoxLayout()
# 模拟器连接控制
self.ip_input = QLineEdit("127.0.0.1", self)
self.port_input = QLineEdit(self.leidian_port, self)
self.connect_btn = QPushButton('连接模拟器', self)
self.connect_btn.clicked.connect(self.connect_emulator)
# 操作按钮
self.launch_btn = QPushButton('启动QQ', self)
self.launch_btn.clicked.connect(self.launch_qq)
self.launch_btn.setEnabled(False)
self.stop_btn = QPushButton('停止QQ', self)
self.stop_btn.clicked.connect(self.stop_qq)
self.stop_btn.setEnabled(False)
self.screenshot_btn = QPushButton('获取截图', self)
self.screenshot_btn.clicked.connect(self.get_screenshot)
self.screenshot_btn.setEnabled(False)
# 状态显示
self.status_label = QLabel('状态: 未连接', self)
self.status_label.setAlignment(Qt.AlignCenter)
# 截图显示
self.screenshot_label = QLabel('截图将显示在这里', self)
self.screenshot_label.setAlignment(Qt.AlignCenter)
self.screenshot_label.setMinimumSize(720, 480)
# 布局
layout.addWidget(QLabel("模拟器IP:"))
layout.addWidget(self.ip_input)
layout.addWidget(QLabel("ADB端口:"))
layout.addWidget(self.port_input)
layout.addWidget(self.connect_btn)
layout.addWidget(self.status_label)
layout.addWidget(self.launch_btn)
layout.addWidget(self.stop_btn)
layout.addWidget(self.screenshot_btn)
layout.addWidget(self.screenshot_label)
self.setLayout(layout)
def run_adb_command(self, command):
"""执行ADB命令"""
try:
full_cmd = f'"{self.adb_path}" -s {self.ip_input.text()}:{self.port_input.text()} {command}'
result = subprocess.run(full_cmd, shell=True, check=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True)
return result.stdout
except subprocess.CalledProcessError as e:
self.status_label.setText(f'ADB错误: {e.stderr}')
return None
def connect_emulator(self):
"""连接雷电模拟器"""
# 检查ADB连接
connect_cmd = f"connect {self.ip_input.text()}:{self.port_input.text()}"
result = subprocess.run(f'"{self.adb_path}" {connect_cmd}', shell=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
text=True)
if "connected" in result.stdout:
self.status_label.setText("状态: 已连接")
self.launch_btn.setEnabled(True)
self.stop_btn.setEnabled(True)
self.screenshot_btn.setEnabled(True)
else:
self.status_label.setText(f"连接失败: {result.stderr or result.stdout}")
def launch_qq(self):
"""启动QQ应用"""
result = self.run_adb_command(f"shell am start -n {self.qq_package}/{self.qq_activity}")
if result:
self.status_label.setText("QQ启动成功")
time.sleep(2) # 等待QQ完全启动
else:
self.status_label.setText("QQ启动失败")
def stop_qq(self):
"""停止QQ应用"""
result = self.run_adb_command(f"shell am force-stop {self.qq_package}")
if result is None: # force-stop无输出
self.status_label.setText("QQ已停止")
def get_screenshot(self):
"""获取屏幕截图"""
temp_file = "qq_screenshot.png"
# 方法1: 直接截图到文件(推荐)
try:
with open(temp_file, "wb") as f:
subprocess.run(
f'"{self.adb_path}" -s {self.ip_input.text()}:{self.port_input.text()} exec-out screencap -p',
shell=True, stdout=f, check=True
)
# 显示截图
pixmap = QPixmap(temp_file)
if not pixmap.isNull():
self.screenshot_label.setPixmap(
pixmap.scaled(
self.screenshot_label.size(),
Qt.KeepAspectRatio,
Qt.SmoothTransformation
)
)
self.status_label.setText("截图获取成功")
else:
self.status_label.setText("截图加载失败")
except Exception as e:
self.status_label.setText(f"截图失败: {str(e)}")
if __name__ == '__main__':
app = QApplication(sys.argv)
controller = QQController()
controller.show()
sys.exit(app.exec_())
使用步骤
1. 配置雷电模拟器
- 打开雷电模拟器多开器
- 点击右下角"设置"按钮
- 在"高级设置"中记下ADB端口号(默认为5555)
- 确保"ADB调试"已开启
2. 运行程序
- 将上述代码保存为
qq_controller.py
- 修改代码中的
adb_path
变量为你的雷电ADB实际路径 - 运行程序:
python qq_controller.py
3. 基本操作流程
- 在程序界面输入模拟器IP(默认127.0.0.1)和ADB端口
- 点击"连接模拟器"按钮
- 连接成功后,使用下方按钮控制QQ:
- “启动QQ”: 启动QQ应用
- “停止QQ”: 强制停止QQ
- “获取截图”: 截取当前屏幕并显示
高级功能扩展
1. 自动登录QQ
def auto_login_qq(self):
"""模拟点击登录按钮(需根据具体分辨率调整坐标)"""
self.run_adb_command("shell input tap 540 800") # 点击QQ登录按钮
time.sleep(1)
self.run_adb_command("shell input text 123456789") # 输入QQ号
self.run_adb_command("shell input keyevent 61") # 切换到密码框
self.run_adb_command("shell input text yourpassword") # 输入密码
self.run_adb_command("shell input tap 540 900") # 点击登录
2. 多开控制
def get_emulator_list(self):
"""获取所有雷电模拟器实例"""
result = subprocess.run(f'"{self.adb_path}" devices', shell=True,
stdout=subprocess.PIPE, text=True)
return [line.split('\t')[0] for line in result.stdout.splitlines()
if '\tdevice' in line]
3. 性能监控
def get_qq_performance(self):
"""获取QQ应用的CPU和内存使用情况"""
cmd = f"shell top -n 1 | findstr {self.qq_package}"
return self.run_adb_command(cmd)
常见问题解决
-
ADB连接失败
- 检查雷电模拟器是否已开启ADB调试
- 确认防火墙没有阻止ADB连接
- 尝试重启ADB服务:
adb kill-server && adb start-server
-
QQ无法启动
- 确认QQ包名和Activity正确
- 尝试清除QQ数据:
adb shell pm clear com.tencent.mobileqq
-
截图失败
- 确保模拟器屏幕已解锁
- 尝试更换截图方法(代码中提供了两种方法)
-
操作延迟
- 适当增加操作间的等待时间
- 降低模拟器分辨率以提高响应速度
通过这个完整的解决方案,你可以轻松实现PyQt与雷电模拟器的交互,并对QQ应用进行自动化控制和监控。