【使用Python编写游戏辅助工具】第五篇:打造交互式游戏工具界面:PySide6/PyQT高效构建GUI工具
前言
这里是【使用Python编写游戏辅助工具】的第五篇:打造交互式游戏工具界面:PySide6/PyQT高效构建GUI工具。本文主要介绍使用
PySide6
来实现构建GUI工具。
在前面,我们实现了两个实用的游戏辅助功能:
- 由键盘监听事件触发的鼠标连击功能;
- 对Windows窗口的多种操作(如隐藏、显示、设置前台等
在这一篇文章中,笔者将带领读者朋友们使用 PySide6/PyQT
将前面实现的功能封装成一个GUI工具,这样一个简单的游戏辅助工具初具雏形了。
即使你完全没有 PySide6/PyQT
这方面的开发经验也没关系,学习就完事了;
即便不想学习,笔者也会提供源码,拿来用就完事了。
本文章为本系列文章最后一篇,【使用Python编写游戏辅助工具】系列文章到此结束。
文章脉络概述
该工具大致的组织架构如下图所示:
- 包含
鼠标连击
、Windows窗口操作
等功能!
在本系列文章中,我们将逐步构建一个游戏辅助工具,它将提供以下主要功能(所有功能都是借助Python
的相关库和模块来帮助我们实现的;):
-
鼠标连击器:实现自动触发连续鼠标点击动作,帮助我们实现连击操作;
-
Windows窗口操作:利用
Python
的相关库和模块,我们将探索如何操作和控制Windows窗口,包括隐藏窗口、显示窗口、置顶窗口等操作;
系列文章脉络
系列文章内容大体如下,后续可能会更新新的文章。
-
点击直达:【使用Python编写游戏辅助工具】第一篇:概述
-
点击直达:【使用Python编写游戏辅助工具】第二篇:键盘监听的应用
-
点击直达:【使用Python编写游戏辅助工具】第三篇:鼠标连击器的实现
-
点击直达:【使用Python编写游戏辅助工具】第四篇:Windows窗口操作
-
点击直达:【使用Python编写游戏辅助工具】第五篇:打造交互式游戏工具界面:PySide6/PyQT高效构建GUI工具
知识点📖📖
库和模块 | 描述 |
---|---|
PySide6/PyQT | 提供了Python与Qt框架的绑定,用于创建图形用户界面(GUI) |
安装依赖
pip install pyside6
这个模块就可以很好的实现本文的主题。
实现
因文章篇幅有限,抓重点来讲。
本文的代码实在是太多了,也不知从哪说起。干脆把代码都贴上来,
操作示例
视频介绍:咸鱼之王后台挂机软件和 鼠标连点器 Python实现
- 下面的动图主要展示了该工具可以最小化到系统托盘,并从系统托盘恢复的操作。
项目组织
使用PySide6/PyQT
构建的GUI工具组织架构如下所示:
- 采用了MVC模型,通过MVC模式的应用,可以实现数据、用户界面和业务逻辑的解耦,提高代码的可读性、可维护性和可测试性;
- 模型、视图和控制器各自担负不同的责任,使代码更具结构化,并允许团队成员分工合作,独立开发和测试各个组件。
GameAssistant/
├── controllers/
│ ├── __init__.py
│ └── controller_main.py
├── make/
│ └── 辅助小工具.spec
├── models/
│ ├── invoke_func/
│ │ ├── __init__.py
│ │ ├── mouse_click.py
│ │ └── window_operate.py
│ ├── __init__.py
│ └── model_main.py
├── views/
│ ├── resources/
│ │ ├── main.ui
│ │ ├── trash.png
│ │ └── utils.qrc
│ ├── ui/
│ │ ├── __init__.py
│ │ ├── main_ui.py
│ │ └── utils_rc.py
│ ├── widgets/
│ │ ├── __init__.py
│ │ └── view_main.py
│ └── __init__.py
├── main.py
├── README.md
└── requirements.txt
绘制GUI界面
在designer.exe
软件中,绘制出下图所示的工具界面(路径在views/resources/main.ui
- 使用了
QTabWidget
控件,绘制了两个页面。- 在
鼠标连击
页面,有一个输入框; - 在
后台挂机
页面,有一个输入框和两个按钮
- 在
这个比较简单,动手拖拽需要的控件,拼凑起来就可以了(有手就行。
如下动图所示:
model(模型)
这里使用了 QRunnable + QThreadPool 实现的线程池,并将所有任务都给到 线程池中运行。
- 鼠标点击 和 Windows操作 的代码放置在(models/invoke_func/ 下
# -*- coding: utf-8 -*-
# Name: model_main.py
# Author: 小菜
# Date: 2023/6/14 20:00
# Description:from collections import defaultdict
from PySide6.QtCore import (QObject, QRunnable, QThreadPool, Signal)from models.invoke_func.mouse_click import click_mouse
from models.invoke_func.window_operate import (show_window, hide_window)flag = Trueclass WorkerRunnable(QRunnable):def __init__(self, func, *args, **kwargs):super().__init__()self.func = funcself.args = argsself.status_signal = kwargs.get('status_signal')def run(self):if not self.args:self.func()while flag:self.func(*self.args)def win_run(self):res = self.func(*self.args)self.status_signal.emit({'status': res})class ModelMain(QObject):win_status_signal: Signal = Signal(dict)def __init__(self):super().__init__()self.thread_pool = QThreadPool()self.thread_status_map = defaultdict(bool)def stop_keyboard_listener(self):global flagif flag:flag = Falsethread_name: str = 'click'self.thread_status_map[thread_name] = Falsedef click_operate(self, frequency: int = 10):global flagthread_name: str = 'click'if self.thread_status_map[thread_name]:returnflag = Trueself.thread_status_map[thread_name] = Trueif frequency < 10:frequency = 10print(flag, thread_name, self.thread_status_map[thread_name], frequency)click_frequency_map = {10: [0.09],20: [0.035],30: [0.027],40: [0.014],50: [0.013],60: [0.005],70: [0.01, 0.01, 0.01, 0.01, 0.01, 0.01, 0],80: [0.01, 0.01, 0.01, 0],90: [0.01, 0.01, 0],100: [0.01, 0.0001, 0.0001, 0, 0],150: [0.001, 0.001, 0, 0, 0]}task = WorkerRunnable(click_mouse,click_frequency_map.get(frequency, 150))self.thread_pool.start(task)def show_win_operate(self, title: str = None):task = WorkerRunnable(show_window,title,status_signal=self.win_status_signal)self.thread_pool.start(task.win_run)def hide_win_operate(self, title: str = None):task = WorkerRunnable(hide_window,title,status_signal=self.win_status_signal)self.thread_pool.start(task.win_run)
view(视图)
视图代码实现了
- 添加工具到系统托盘,从系统托盘退出或恢复工具;
- 按下键盘的
Esc
就最小化到系统托盘;
# -*- coding: utf-8 -*-
# Name: view_main.py
# Author: 小菜
# Date: 2023/6/14 20:00
# Description:
import osfrom PySide6.QtGui import (QAction, QIcon, QShortcut, QKeySequence)
from PySide6.QtWidgets import (QMainWindow, QSystemTrayIcon, QMenu)from views import Ui_MainWindowclass ViewMain(QMainWindow, Ui_MainWindow):def __init__(self, parent=None) -> None:super().__init__(parent=parent)self.setupUi(self)# 创建系统托盘图标相关的变量和对象self._restore_action = QAction()self._quit_action = QAction()self._tray_icon_menu = QMenu()# 创建系统托盘图标self.tray_icon = QSystemTrayIcon(self)self.tray_icon.setIcon(QIcon(u":/trash.png"))self.tray_icon.setToolTip("辅助小工具")# 创建系统托盘图标的菜单和动作self.create_actions()self.create_tray_icon()self.tray_icon.show()# 连接系统托盘图标的激活信号到槽函数self.tray_icon.activated.connect(self.tray_icon_activated)# 键盘监听self.listen_keyboard()def tray_icon_activated(self, reason):# 当系统托盘图标被激活时的操作if reason == QSystemTrayIcon.ActivationReason.Trigger:self.restore_from_tray()def restore_from_tray(self):# 还原窗口if self.isMinimized():self.showNormal()elif self.isMaximized():self.showMaximized()else:self.show()def create_actions(self):# 创建系统托盘图标菜单的动作self._restore_action = QAction("显示", self)self._restore_action.triggered.connect(self.restore_from_tray) # "显示"菜单项触发还原窗口的操作self._quit_action = QAction("退出", self)self._quit_action.triggered.connect(lambda: os._exit(0)) # "退出"菜单项触发退出应用程序的操作def create_tray_icon(self):# 创建系统托盘图标的菜单self._tray_icon_menu = QMenu(self)self._tray_icon_menu.addAction(self._restore_action)self._tray_icon_menu.addSeparator()self._tray_icon_menu.addAction(self._quit_action)self.tray_icon.setContextMenu(self._tray_icon_menu)self.tray_icon.show()def show_notification(self, title: str = '连击信息⚠', text: str = None, icon=QSystemTrayIcon.MessageIcon.Information):# 显示系统通知self.tray_icon.showMessage(title,f"警告!!!{text}",icon,2000)def listen_keyboard(self):# 键盘监听shortcut = QShortcut(QKeySequence("Esc"), self)# 当按下 Esc 键时隐藏窗口shortcut.activated.connect(self.hide)
controller(控制器)
这里做的操作是将 model与view连接起来,充当了一个中间人的活儿。
# -*- coding: utf-8 -*-
# Name: controller_main.py
# Author: 小菜
# Date: 2023/6/14 20:00
# Description:import keyboard
from PySide6.QtCore import Slot
from PySide6.QtWidgets import QSystemTrayIconfrom views import ViewMain
from models import (ModelMain, WorkerRunnable)round_to_nearest_10 = lambda number: min(round(number / 10) * 10, 150)class ControllerMain:def __init__(self):self.view = ViewMain()self.model = ModelMain()# 显示窗口self.view.show()# 初始化 键盘监听self.init_operate()# 绑定按钮self.view.btn_show_win.clicked.connect(self.show_win_operate)self.view.btn_hide_win.clicked.connect(self.hide_win_operate)# 绑定信号到槽函数self.model.win_status_signal.connect(self.window_listen)def init_operate(self):task = WorkerRunnable(self.listen_keyboard)self.model.thread_pool.start(task)def listen_keyboard(self):keyboard.add_hotkey('Ctrl+Shift+A', self.click_operate)keyboard.add_hotkey('Ctrl+Shift+Q', self.model.stop_keyboard_listener)keyboard.wait()def click_operate(self):frequency = 10# 创建匿名函数try:frequency = round_to_nearest_10(int(self.view.line_edit_click.text()))print(frequency)except (ValueError, TypeError):...finally:self.model.click_operate(frequency=frequency)self.view.show_notification(text='开始点击')def show_win_operate(self):win_title = self.view.line_edit_title.text()if not win_title:returnself.model.show_win_operate(title=win_title)def hide_win_operate(self):win_title = self.view.line_edit_title.text()if not win_title:returnself.model.hide_win_operate(title=win_title)@Slot(dict)def window_listen(self, item):if not item.get('status'):self.view.show_notification(title='警告警告⚠',text='找不到窗口!!!',icon=QSystemTrayIcon.MessageIcon.Warning)
main函数
函数启动入口
# -*- coding: utf-8 -*-
# Name: main.py
# Author: 小菜
# Date: 2023/6/14 20:00
# Description:import sys
from ctypes import windllfrom PySide6.QtWidgets import QApplicationfrom controllers import ControllerMainif __name__ == '__main__':# 同步图标windll.shell32.SetCurrentProcessExplicitAppUserModelID('nothing')app = QApplication()# 关闭窗口时候不退出程序app.setQuitOnLastWindowClosed(False)controller = ControllerMain()# 事件循环sys.exit(app.exec())
总结🎈🎈
本文介绍了 PySide6/PyQT
打包游戏辅助工具的操作。
将前面介绍的 鼠标连点
、Windows窗口操作
等功能打包成一个GUI工具,从更加方便后续的使用。
总而言之,本文通过详细介绍使用 PySide6/PyQT
打包GUI的操作,帮助读者理解和应用Python在游戏辅助工具开发中的打包功能。
相关文章:

【使用Python编写游戏辅助工具】第五篇:打造交互式游戏工具界面:PySide6/PyQT高效构建GUI工具
前言 这里是【使用Python编写游戏辅助工具】的第五篇:打造交互式游戏工具界面:PySide6/PyQT高效构建GUI工具。本文主要介绍使用PySide6来实现构建GUI工具。 在前面,我们实现了两个实用的游戏辅助功能: 由键盘监听事件触发的鼠标连…...

06.Oracle数据备份与恢复
Oracle数据备份与恢复 一、通过RMAN方式备份二、使用emp/imp和expdb/impdb工具进行备份和恢复三、使用Data guard进行备份与恢复 一、通过RMAN方式备份 通过 RMAN(Oracle 数据库备份和恢复管理器)方式备份 Oracle 数据库,可以使用以下步骤&a…...

大航海时代Ⅳ 威力加强版套装 HD Version (WinMac)中文免安装版
《大航海时代》系列的人气SRPG《大航海时代IV》以HD的新面貌再次登场!本作品以16世纪的欧洲“大航海时代”为舞台,玩家将以探险家、商人、军人等不同身份与全世界形形色色的人们一起上演出跌宕起伏的海洋冒险。游戏中玩家的目的是在不同的海域中掌握霸权…...

微信小程序 uCharts的使用方法
一、背景 微信小程序项目需要渲染一个柱状图,使用uCharts组件完成 uCharts官网指引👉:uCharts官网 - 秋云uCharts跨平台图表库 二、实现效果 三、具体使用 进入官网查看指南,有两种方式进行使用:分别是原生方式与组…...

面试算法54:所有大于或等于节点的值之和
题目 给定一棵二叉搜索树,请将它的每个节点的值替换成树中大于或等于该节点值的所有节点值之和。假设二叉搜索树中节点的值唯一。例如,输入如图8.10(a)所示的二叉搜索树,由于有两个节点的值大于或等于6(即…...

七月论文审稿GPT第二版:从Meta Nougat、GPT4审稿到LongLora版LLaMA、Mistral
前言 如此前这篇文章《学术论文GPT的源码解读与微调:从chatpaper、gpt_academic到七月论文审稿GPT》中的第三部分所述,对于论文的摘要/总结、对话、翻译、语法检查而言,市面上的学术论文GPT的效果虽暂未有多好,可至少还过得去&am…...

PyTorch入门学习(十二):神经网络-搭建小实战和Sequential的使用
目录 一、介绍 二、先决条件 三、代码解释 一、介绍 在深度学习领域,构建复杂的神经网络模型可能是一项艰巨的任务,尤其是当您有许多层和操作需要组织时。幸运的是,PyTorch提供了一个方便的工具,称为Sequential API,…...

Linux shell编程学习笔记20:case ... esac、continue 和break语句
一、case ... esac语句说明 在实际编程中,我们有时会请到多条件多分支选择的情况,用if…else语句来嵌套处理不烦琐,于是JavaScript等语言提供了多选择语句switch ... case。与此类似,Linux Shell脚本编程中提供了case...in...esa…...

树莓派4无法进入桌面模式(启动后出现彩色画面,然后一直黑屏,但是可以正常启动和ssh)
本文记录了这段比较坎坷的探索之路,由于你的问题不一定是我最终解决方案的,可能是前面探索路上试过的,所以建议按顺序看排除前置问题。 双十一又买了个树莓派 4B,插上之前树莓派 4B 的 TF 卡直接就能使用(毕竟是一样规…...

花草世界生存技能
多菌灵 杀菌常用 阿维菌素 杀虫常用 除蚜虫 吡虫啉 有毒性 内吸性(植物吸收) 苦参碱 无毒,中药提取 内吸性药 吡虫啉,噻虫嗪、啶虫脒、苦参碱 栀子花 春秋花后修剪 牡丹 秋冬种植; 洛阳产地; 肥料 …...

执行npm install时老是安装不成功node-sass的原因和解决方案
相信你安装前端项目所需要的依赖包(npm install 或 yarn install)时,有可能会出现如下报错: D:\code\**project > yarn install ... [4/4] Building fresh packages... [-/6] ⠁ waiting... [-/6] ⠂ waiting... [-/6] ⠂ wai…...

【MongoDB】集群搭建实战 | 副本集 Replica-Set | 分片集群 Shard-Cluster | 安全认证
文章目录 MongoDB 集群架构副本集主节点选举原则搭建副本集主节点从节点仲裁节点 连接节点添加副本从节点添加仲裁者节点删除节点 副本集读写操作副本集中的方法 分片集群分片集群架构目标第一个副本集第二个副本集配置集初始化副本集路由集添加分片开启分片集合分片删除分片 安…...

「Verilog学习笔记」四选一多路器
专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点,刷题网站用的是牛客网 分析 通过波形示意图我们可以发现,当sel为0,1,2时,输出mux_out分别为d3,d2,d1,那么sel3…...

asp.net 创建docker容器
首先创建asp.net web api 创建完成后如下图 添加docker支持 添加docker支持 添加linux docker支持...

Linux项目自动化构建工具-make/Makefile使用
make/Makefile使用介绍 make是一个命令makefile是一个在当前目录下存在的一个具有特定格式的文本文件 下面我们设计一个场景,实现make命令对我们code.c文件进行编译和删除。 1 #include<stdio.h> 2 3 int main() 4 { 5 printf("hello,world!…...

【React】03.脚手架的进阶应用
文章目录 暴露webpack配置暴露前后的区别config文件夹:scripts文件夹:package.json 常见的配置修改1.把sass改为less2.配置别名3.修改域名和端口号4.修改浏览器兼容5.处理Proxy跨域 2023年最新珠峰React全家桶【react基础-进阶-项目-源码-淘系-面试题】 …...

WPF开源控件HandyControl——零基础教程
学习Handycontrol的过程中,为后边快速开发,写的零基础教程,尽量看完就可以实践! 参考教程 中文文档:欢迎使用HandyControl | HandyOrg Github代码:https://github.com/HandyOrg/HandyControl 使用教程:WPF-HandyControl安装和使用 - 掘金 安装配置教程 创建wpf项目 …...

chinese-stable-diffusion中文场景文生图prompt测评集合
腾讯混元大模型文生图操作指南.dochttps://mp.weixin.qq.com/s/u0AGtpwm_LmgnDY7OQhKGg腾讯混元大模型再进化,文生图能力重磅上线,这里是一手实测腾讯混元的文生图在人像真实感、场景真实感上有比较明显的优势,同时,在中国风景、动…...

K-均值聚类算法
K-均值聚类算法是一种常用的无监督学习算法,目的是将一组数据点分为 K 个聚类。它的主要思想是通过迭代的方式不断调整聚类中心的位置,使得数据点与最近的聚类中心之间的距离最小。 算法步骤如下: 初始化 K 个聚类中心,可以随机…...

Xbox漫游指南
以Xbox series s为例 开机启动 用手柄连接,注意两颗电池要方向相反插入,虽然里面2个插槽长一样; Xbox APP极其难用,放弃,直接用手柄连接 转区 只需要一个空U盘,大小不限制,格式化为NTPS格式…...

降低毕业论文写作压力的终极指南
亲爱的同学们,时光荏苒,转眼间你们即将踏入毕业生的行列。毕业论文作为本科和研究生阶段的重要任务,不仅是对所学知识的综合运用,更是一次对自己学术能力和专业素养的全面考验。然而,论文写作常常伴随着压力和焦虑&…...

SELECT COUNT( * ) 与SELECT COUNT( 1 ) 区别
在 SQL 中,SELECT COUNT(*) 和 SELECT COUNT(1) 都用于统计符合条件的行数,但它们在具体实现和效率上有一些区别。 SELECT COUNT(*):这是一种常见且通用的写法,它会统计所有符合查询条件的行数,包括所有列,…...

[python 刷题] 1248 Count Number of Nice Subarrays
[python 刷题] 1248 Count Number of Nice Subarrays 题目如下: Given an array of integers nums and an integer k. A continuous subarray is called nice if there are k odd numbers on it. Return the number of nice sub-arrays. 这道题和 1343 Number of S…...

堆叠注入 [GYCTF2020]Blacklist1
打开题目 判断注入点 输入1,页面回显 输入1 页面报错 输入 1 # 页面正常,说明是单引号的字符型注入 我们输入1; show databases; # 说明有6个数据库 1; show tables; # 说明有三个表 我们直接查看FlagHere的表结构 1;desc FlagHere;# 发…...

算法:Java构建二叉树并递归实现二叉树的前序、中序、后序遍历
先自定义一下二叉树的类: // Definition for a binary tree node. public class TreeNode {int val;TreeNode left;TreeNode right;TreeNode() {}TreeNode(int val) { this.val val; }TreeNode(int val, TreeNode left, TreeNode right) {this.val val;this.left…...

既然有了字节流,为什么还要有字符流?
字符流和字节流之间的区别主要在于它们处理数据的方式和用途: 字节流:字节流以字节为单位进行数据的读取和写入,适用于处理二进制数据,如图像、音频和视频文件。字节流是处理底层数据的理想选择,它不会对数据进行编码…...

3+单细胞+代谢+WGCNA+机器学习
今天给同学们分享一篇生信文章“Identification of new co-diagnostic genes for sepsis and metabolic syndrome using single-cell data analysis and machine learning algorithms”,这篇文章发表Front Genet.期刊上,影响因子为3.7。 结果解读&#x…...

音乐推荐与管理系统Python+Django网页界面+协同过滤推荐算法
一、介绍 音乐推荐与管理系统。本系统采用Python作为主要开发语言,前端使用HTML、CSS、BootStrap等技术搭建界面平台,后端使用Django框架处理请求,并基于Ajax等技术实现前端与后端的数据通信。在音乐个性推荐功能模块中采用通过Python编写协…...

(论文阅读15/100)You Only Look Once: Unified, Real-Time Object Detection
文献阅读笔记 简介 题目 You Only Look Once: Unified, Real-Time Object Detection 作者 Joseph Redmon, Santosh Divvala, Ross Girshick, Ali Farhadi 原文链接 https://arxiv.org/pdf/1506.02640.pdf 《You Only Look Once: Unified, Real-Time Object Detection》…...

init进程启动过程
首语 init进程是Android系统中用户空间的第一个进程,进程号为1,是Android系统启动的一个关键步骤,作为第一个进程,它的主要工作是创建Zygote和启动属性服务等。init进程是由多个源文件共同组成的,源码目录在system/co…...