写一个自动化记录鼠标/键盘的动作,然后可以重复执行的python程序

news2024/9/19 17:26:14
import sys
import threading
import time
from PyQt5.QtWidgets import *
from auto_fun import *
import pyautogui
import pynput
from PyQt5.QtCore import pyqtSignal
from MouseModule import *
from pynput import keyboard

local_list = []  # 保存操作坐标、动作、文本
begain_time = 0
now_time = 0
text_list = []
input_str = ""  # 从键盘输入的数据
click_flag = False
keyborad_flag = False


class window(QMainWindow, Ui_MainWindow):
    lcd_signal = pyqtSignal(int)  # 循环计数信号
    display_signal = pyqtSignal(str)  # 操作记录显示信号

    def __init__(self):
        super(window, self).__init__()
        self.mouse_active = False
        self.mouse_listener = None
        self.keyboard_active = False
        self.keyboard_listener = None
        self.setupUi(self)
        self.init()

    #初始化
    def init(self):
        self.pushButton_3.clicked.connect(self.begin_note)
        self.pushButton_4.clicked.connect(self.begin_action)
        self.lcd_signal.connect(self.lcd_signal_fun)               #信号触发计时
        self.display_signal.connect(self.display_signal_fun)      #信号触发显示界面

    def keyboard_start(self):
        self.keyboard_active = True
        self.keyboard_listener = keyboard.Listener(on_press=self.on_press)
        self.keyboard_listener.start()

    def keyboard_stop(self):
        if self.keyboard_listener:
            self.keyboard_active = False
            self.keyboard_listener.stop()

    def on_press(self,key):
        global input_str
        global begain_time
        print("键盘事件:", key)
        test_key = str(key)  # 必须有这一步否则会出问题 崩溃
        str_data = test_key.replace("'", "")

        if str_data == "Key.enter":
            str_data = '\n'

        if "Key" not in str_data:
            input_str = input_str + str_data
            now_time = time.time()
            action = {}
            action["act"] = "note"
            action["input_text"] = input_str  # 键盘输入的数据   如果需要回车需要贾’\n‘
            action["sleep"] = int((now_time - begain_time)) + 1  # 保存延迟的时间
            begain_time = now_time
            local_list.append(action)
            print(local_list)
            input_str = ''
            self.display_signal.emit("输入文本:" + action["input_text"])

    def mouse_start(self):
        self.mouse_active = True
        self.mouse_listener = mouse.Listener(on_click=self.on_click)
        self.mouse_listener.start()

    def mouse_stop(self):
        if self.mouse_listener:
            self.mouse_active = False
            self.mouse_listener.stop()

    def on_click(self, x, y, button, pressed):
        global begain_time
        global local_list
        if self.mouse_active:
            if pressed:
                print('Button {0} pressed at ({1}, {2})'.format(button, x, y))
                action = {}
                action["local"] = [x, y]
                action["act"] = "click"
                now_time = time.time()
                action["sleep"] = int((now_time - begain_time)) + 1  # 保存延迟的时间
                begain_time = now_time
                local_list.append(action)  # local_list 操作记录表格
                self.display_signal.emit("点击坐标:" + str(x) + " " + str(y))

    def display_signal_fun(self, text):
        self.textEdit.insertPlainText(text + '\n')

    def lcd_signal_fun(self, num):
        self.lcdNumber.display(num + 1)
        print("动作执行:", num)

    def action_thread(self):
        global local_list
        num = self.spinBox.text()
        print("开始执行动作循环")
        for i in range(0, int(num)):
            for item in local_list:
                if item["act"] == "click":
                    pyautogui.click(int(item["local"][0]), int(item["local"][1]))
                    time.sleep(item["sleep"])
                    print("鼠标点击", item["local"][0], item["local"][1])

                elif item['act'] == "note":
                    pyautogui.typewrite(item["input_text"])
                    time.sleep(item["sleep"])
            self.lcd_signal.emit(i)

    # 创建一个线程开始执行记录的动作
    def begin_action(self):
        fd = threading.Thread(target=self.action_thread)
        fd.start()

    # 开始记录动作
    def begin_note(self):
        global begain_time
        global click_flag
        global keyborad_flag
        global local_list
        if self.pushButton_3.text() == "开始录制":
            self.pushButton_3.setText("停止录制")
            local_list = []  # 清空指令列表
            self.mouse_start()
            self.keyboard_start()
            begain_time = time.time()

        elif self.pushButton_3.text() == "停止录制":
            self.pushButton_3.setText("开始录制")
            print("停止录制")
            self.mouse_stop()
            self.keyboard_stop()
            local_list.pop()
            print("动作执行列表:", local_list)

def main():
    app = QApplication(sys.argv)
    win = window()
    win.show()
    sys.exit(app.exec_())


if __name__ == '__main__':
    main()

##ui界面
# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'auto_fun.ui'
#
# Created by: PyQt5 UI code generator 5.15.9
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again.  Do not edit this file unless you know what you are doing.


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(600, 300)
        MainWindow.setMinimumSize(QtCore.QSize(600, 300))
        MainWindow.setMaximumSize(QtCore.QSize(600, 300))
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.centralwidget)
        self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
        self.horizontalLayout_2.setSpacing(0)
        self.horizontalLayout_2.setObjectName("horizontalLayout_2")
        self.frame_2 = QtWidgets.QFrame(self.centralwidget)
        self.frame_2.setMinimumSize(QtCore.QSize(290, 290))
        self.frame_2.setMaximumSize(QtCore.QSize(290, 290))
        self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame_2.setObjectName("frame_2")
        self.lcdNumber = QtWidgets.QLCDNumber(self.frame_2)
        self.lcdNumber.setGeometry(QtCore.QRect(70, 30, 131, 51))
        self.lcdNumber.setStyleSheet("background-color: rgb(0, 111, 166);")
        self.lcdNumber.setObjectName("lcdNumber")
        self.pushButton_3 = QtWidgets.QPushButton(self.frame_2)
        self.pushButton_3.setGeometry(QtCore.QRect(20, 200, 75, 23))
        self.pushButton_3.setStyleSheet("QPushButton\n"
"{\n"
"    /*字体为微软雅黑*/\n"
"    font-family:Microsoft Yahei;\n"
"    /*字体大小为20点*/\n"
"    font-size:10pt;\n"
"    /*字体颜色为白色*/    \n"
"    color:white;\n"
"    /*背景颜色*/  \n"
"    background-color:rgb(170 , 170 , 170);\n"
"    /*边框圆角半径为8像素*/ \n"
"    border-radius:8px;\n"
"}\n"
"QPushButton:hover\n"
"{\n"
"    /*背景颜色*/  \n"
"    background-color:rgb(44 , 137 , 255);\n"
"}\n"
"\n"
"QPushButton:pressed\n"
"{\n"
"    /*背景颜色*/  \n"
"    background-color:rgb(14 , 135 , 228);\n"
"    /*左内边距为3像素,让按下时字向右移动3像素*/  \n"
"    padding-left:3px;\n"
"    /*上内边距为3像素,让按下时字向下移动3像素*/  \n"
"    padding-top:3px;\n"
"}")
        self.pushButton_3.setObjectName("pushButton_3")
        self.pushButton_4 = QtWidgets.QPushButton(self.frame_2)
        self.pushButton_4.setGeometry(QtCore.QRect(170, 200, 75, 23))
        self.pushButton_4.setStyleSheet("QPushButton\n"
"{\n"
"    /*字体为微软雅黑*/\n"
"    font-family:Microsoft Yahei;\n"
"    /*字体大小为20点*/\n"
"    font-size:10pt;\n"
"    /*字体颜色为白色*/    \n"
"    color:white;\n"
"    /*背景颜色*/  \n"
"    background-color:rgb(170 , 170 , 170);\n"
"    /*边框圆角半径为8像素*/ \n"
"    border-radius:8px;\n"
"}\n"
"QPushButton:hover\n"
"{\n"
"    /*背景颜色*/  \n"
"    background-color:rgb(44 , 137 , 255);\n"
"}\n"
"\n"
"QPushButton:pressed\n"
"{\n"
"    /*背景颜色*/  \n"
"    background-color:rgb(14 , 135 , 228);\n"
"    /*左内边距为3像素,让按下时字向右移动3像素*/  \n"
"    padding-left:3px;\n"
"    /*上内边距为3像素,让按下时字向下移动3像素*/  \n"
"    padding-top:3px;\n"
"}")
        self.pushButton_4.setObjectName("pushButton_4")
        self.layoutWidget = QtWidgets.QWidget(self.frame_2)
        self.layoutWidget.setGeometry(QtCore.QRect(80, 140, 104, 22))
        self.layoutWidget.setObjectName("layoutWidget")
        self.formLayout = QtWidgets.QFormLayout(self.layoutWidget)
        self.formLayout.setContentsMargins(0, 0, 0, 0)
        self.formLayout.setObjectName("formLayout")
        self.spinBox = QtWidgets.QSpinBox(self.layoutWidget)
        self.spinBox.setObjectName("spinBox")
        self.formLayout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.spinBox)
        self.label = QtWidgets.QLabel(self.layoutWidget)
        self.label.setStyleSheet("font: 75 11pt \"Agency FB\";")
        self.label.setObjectName("label")
        self.formLayout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.label)
        self.horizontalLayout_2.addWidget(self.frame_2)
        self.frame = QtWidgets.QFrame(self.centralwidget)
        self.frame.setMinimumSize(QtCore.QSize(290, 290))
        self.frame.setMaximumSize(QtCore.QSize(290, 290))
        self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame.setObjectName("frame")
        self.gridLayout = QtWidgets.QGridLayout(self.frame)
        self.gridLayout.setContentsMargins(0, 0, 0, 0)
        self.gridLayout.setSpacing(0)
        self.gridLayout.setObjectName("gridLayout")
        self.pushButton_2 = QtWidgets.QPushButton(self.frame)
        self.pushButton_2.setStyleSheet("/*按钮按下态*/\n"
"QPushButton:pressed\n"
"{\n"
"    /*背景颜色*/  \n"
" \n"
"    /*左内边距为3像素,让按下时字向右移动3像素*/  \n"
"    padding-left:3px;\n"
"    /*上内边距为3像素,让按下时字向下移动3像素*/  \n"
"    padding-top:3px;\n"
"}")
        self.pushButton_2.setObjectName("pushButton_2")
        self.gridLayout.addWidget(self.pushButton_2, 1, 1, 1, 1)
        self.textEdit = QtWidgets.QTextEdit(self.frame)
        self.textEdit.setMinimumSize(QtCore.QSize(200, 200))
        self.textEdit.setMaximumSize(QtCore.QSize(290, 290))
        self.textEdit.setStyleSheet("background-color: rgb(0, 0, 0);\n"
"color: rgb(255, 255, 255);")
        self.textEdit.setObjectName("textEdit")
        self.gridLayout.addWidget(self.textEdit, 0, 0, 1, 2)
        self.pushButton = QtWidgets.QPushButton(self.frame)
        self.pushButton.setStyleSheet("/*按钮按下态*/\n"
"QPushButton:pressed\n"
"{\n"
"    /*背景颜色*/  \n"
"    /*左内边距为3像素,让按下时字向右移动3像素*/  \n"
"    padding-left:3px;\n"
"    /*上内边距为3像素,让按下时字向下移动3像素*/  \n"
"    padding-top:3px;\n"
"}")
        self.pushButton.setObjectName("pushButton")
        self.gridLayout.addWidget(self.pushButton, 1, 0, 1, 1)
        self.horizontalLayout_2.addWidget(self.frame)
        MainWindow.setCentralWidget(self.centralwidget)

        self.retranslateUi(MainWindow)
        # self.pushButton_4.clicked.connect(MainWindow.lower) # type: ignore
        self.pushButton_2.clicked.connect(self.textEdit.clear) # type: ignore
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton_3.setText(_translate("MainWindow", "开始录制"))
        self.pushButton_4.setText(_translate("MainWindow", "执行"))
        self.label.setText(_translate("MainWindow", "执行次数"))
        self.pushButton_2.setText(_translate("MainWindow", "清空记录"))
        self.pushButton.setText(_translate("MainWindow", "保存记录"))

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2143740.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2024年9月12日美国Embarcadero公司正式发布RAD Studio Delphi/C++ Builder 12.2 雅典

Embarcadero 非常高兴地宣布,从今天开始,RAD Studio 12.2 Athens 以及 Delphi 12.2 和 CBuilder 12.2 可供客户使用。RAD Studio 12.2 Athens 版本提供了我们在 IDE 中的第一次生成式 AI 集成、用于 Web 开发的新模板库、基于 C Win64 Clang 的新编译器和…

【MATLAB源码-第266期】基于Matlab的k-means算法遥感图像分割系统仿真。

操作环境: MATLAB 2022a 1、算法描述 基于K-means算法的图像分割在遥感图像处理中的应用十分广泛,尤其是对于需要自动提取特定区域或目标的场景。遥感图像通常包含了大量的地物信息,不同的地物如水体、建筑物、植被等在遥感图像中会表现出…

电脑的主板,内存条插多少合适?

首先,不是插满4条内存就是最好的。 内存条插得多,确实可以扩充容量,提升性能。但是有些低端的主板配低端CPU,插满4条内存,稳定性下降。这里的稳定性包括供电,单独的内存供电容量等。此时CPU会通过降低内存…

为什么使用 Rust over C++ 进行 IoT 解决方案开发

物联网已成为我们日常生活中不可或缺的一部分,设备也越来越智能。随着该领域的扩展,迫切需要保证这些支持软件的设备的安全性、生产力和效率。因此,Rust 编程语言正在成为 IoT 设备开发人员仅次于 C 的第二大热门选择。本文将探讨为什么 Rust…

《机器学习》周志华-CH7(贝叶斯分类)

7.1贝叶斯决策论 对分类任务而言,在所有相关概率已知的理想情形下,贝叶斯决策论考虑如何基于这些概率核误判损失来选择最优的类别标记。 R ( x i ∣ x ) ∑ j 1 N λ i j P ( c j ∣ x ) \begin{equation} R(x_{i}|x)\sum_{j1}^{N}\lambda_{ij}P(c_{j}…

【C++】vector详解,模拟实现

目录 1. vector的介绍 2. vector的使用 2.1 构造函数 2.2 遍历方式 2.3 reserve与resize 2.4 shrink_to_fit 2.5 insert,erase,find 3. vector模拟实现 3.1 初始结构 3.2 析构函数 3.3 获取容量和元素个数 3.4 扩容reserve 3.5 resize改变…

最新简洁大方的自动发卡网站源码/鲸发卡v11.61系统源码/修复版

源码简介: 最新简洁大方的自动发卡网站源码,它就是鲸发卡v11.61系统源码,它是修复版。 说到鲸发卡系统,鲸发卡系统在发卡圈很多人都知道的,它是市面最好发卡系统之一,操作起来简单得很,界面也…

【数据结构】排序算法---快速排序

文章目录 1. 定义2. 算法步骤3. 动图演示4. 性质5. 递归版本代码实现5.1 hoare版本5.2 挖坑法5.3 lomuto前后指针 6. 优化7. 非递归版本代码实现结语 1. 定义 快速排序是由东尼霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要 O ( n l o g n ) Ο(nlogn) …

在 Windows 上恢复已删除的 PDF 文件的最佳方法

如果您不小心删除了 PDF 文件或由于系统突然崩溃而无法再找到它们,本指南介绍了恢复已删除文件的最佳方法。 帖子中列出的方法简单、有效且可行。我们在列出它们之前对其进行了测试。 什么是 PDF,Adobe 将未保存的 PDF 存储在哪里? 自从 Ad…

数据清洗-缺失值填充-K-NN算法(K-Nearest Neighbors, K-NN算法)

目录 一、安装所需的python包二、采用K-NN算法进行缺失值填充2.1可直接运行代码2.2以某个缺失值数据进行实战2.2.1代码运行过程截屏:2.2.2填充后的数据截屏: 三、K 近邻算法 (K-Nearest Neighbors, KNN) 介绍3.1 K 近邻算法定义3.2 K 近邻算法的基本思想…

Linux 文件与目录操作命令详解

文章目录 前言创建文件1. touch2. vim 文件内容显示3. cat4. more5. less6. head7. tail 文件(目录)复制、删除和移动8. cp9. rm10. mv 压缩文件与解压缩11. gzip12. zip 和 unzip 创建目录13. mkdir 删除目录14. rmdir 改变工作目录15. cd16. pwd 显示目…

六、二分搜索-算法总结

文章目录 六、二分搜索6.1 简介6.2 典型实例 -- 二分查找6.2 模板6.3 常见题目6.3.1 搜索插入位置6.3.2 搜索二维矩阵6.3.3 寻找旋转排序中数组中的最小值6.3.4 寻找旋转排序数组中的最小值 II6.3.5 搜索旋转排序数组6.3.6 搜索旋转排序数组 II 总结 六、二分搜索 6.1 简介 给…

Java或者前端 实现中文排序(调API的Demo)

目录 前言1. 前端2. Java 前言 前端 Vue 中的中文排序通常使用 JavaScript 提供的 localeCompare 方法来比较中文字符串 Java 后端可以使用 Collator 类来实现中文排序 1. 前端 在 Vue 中&#xff0c;使用 localeCompare 来实现中文字符串的排序&#xff1a; <template&…

Skyeye 云智能制造 v3.14.5 发布,ERP 商城

Skyeye 云智能制造&#xff0c;采用 Springboot winUI 的低代码平台、移动端采用 UNI-APP。包含 30 多个应用模块、50 多种电子流程&#xff0c;CRM、PM、ERP、MES、ADM、EHR、笔记、知识库、项目、门店、商城、财务、多班次考勤、薪资、招聘、云售后、论坛、公告、问卷、报表…

SAM 2: Segment Anything in Images and Videos

SAM2: 在图像和视频中分割任何内容 作者 Nikhila Ravi, Valentin Gabeur, Yuan-Ting Hu, Ronghang Hu 等 (Meta FAIR) 论文&#xff1a;SAM2: Segment Anything in Images and Videos项目代码&#xff1a;GitHub Repository互动演示&#xff1a;Demo 摘要 SAM2 是一个用于处…

基于51单片机的锅炉温度控制系统PID调节proteus仿真

地址&#xff1a; https://pan.baidu.com/s/17oMgAnUBUKKEVnv5hNRQmQ 提取码&#xff1a;1234 仿真图&#xff1a; 芯片/模块的特点&#xff1a; AT89C52/AT89C51简介&#xff1a; AT89C52/AT89C51是一款经典的8位单片机&#xff0c;是意法半导体&#xff08;STMicroelectro…

招聘数据分析师,HR会考察候选人哪些方面?

数据分析是必须具备深厚的专业技能底蕴&#xff0c;这是最基本的要求&#xff0c;其中包括对数据分析工具和编程语言的精通&#xff0c;以及对数据库管理的实验操作。 在数据分析师的招聘过程中&#xff0c;必须要注重对方掌握的知识&#xff0c;比如数据挖掘数据可视化等先进…

Qt构建JSON及解析JSON

目录 一.JSON简介 JSON对象 JSON数组 二.Qt中JSON介绍 QJsonvalue Qt中JSON对象 Qt中JSON数组 QJsonDocument 三.Qt构建JSON数组 四.解析JSON数组 一.JSON简介 一般来讲C类和对象在java中是无法直接直接使用的&#xff0c;因为压根就不是一个规则。但是他们在内存中…

详解:Tensorflow、Pytorch、Keras(搭建自己的深度学习网络)

这是一个专门对Tensorflow、Pytorch、Keras三个主流DL框架的一个详解和对比分析 一、何为深度学习框架&#xff1f; 你可以理解为一个工具帮你构建一个深度学习网络&#xff0c;调用里面的各种方法就能自行构建任意层&#xff0c;diy你想要的DNN&#xff0c;而且任意指定学习…

揭秘!当业务方需求模糊,产品经理如何施展‘化雾为金’的神奇策略!

引言 在产品管理的实践中&#xff0c;产品经理经常会遇到业务方无法清晰表达需求的情况。这可能是由于业务方对问题的理解不够深入&#xff0c;或者缺乏将业务需求转化为产品需求的经验。作为资深产品经理&#xff0c;我们需要采取一系列策略来应对这一挑战&#xff0c;确保产…