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

news/2024/9/19 8:58:35 标签: python, 自动化, 计算机外设
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.niftyadmin.cn/n/5665294.html

相关文章

南昌大学-计算机科学与技术专业-预推免-专业课(408)复试面试准备

一、数据结构与算法 1. 什么是时间复杂度和空间复杂度? 时间复杂度用于描述算法的执行时间与输入规模之间的关系,即当输入规模增加时,算法的运行时间如何变化。它主要衡量算法的效率和性能。 空间复杂度用于描述算法在运行过程中所需内存空…

golang学习笔记28——golang中实现多态与面向对象

推荐学习文档 golang应用级os框架,欢迎stargolang应用级os框架使用案例,欢迎star案例:基于golang开发的一款超有个性的旅游计划app经历golang实战大纲golang优秀开发常用开源库汇总想学习更多golang知识,这里有免费的golang学习笔…

家居小程序有什么用?

家居小程序在现代家居生活中扮演着越来越重要的角色,其功能和用途广泛且实用。以下是家居小程序的主要用途: 一、商品展示与购物 商品展示:家居小程序可以展示各种家居产品,包括家具、家电、装饰品等,用户可以通过分类…

计算机网络基础 - 应用层(3)

计算机网络基础 应用层P2P 应用P2P 体系结构的扩展性BitTorrent 协议torrenl 洪流BitTorrent 运行的过程 P2P文件共享应用非结构化 P2PDHT 结构化 P2P(了解) 视频流和内容分发网视频流化服务HTTP 流和 DASH内容分发网 CDN面临挑战CDN 概述CDN 操作过程集…

Flutter问题记录 - 适配Xcode 16和iOS 18

文章目录 前言开发环境问题及解决方案1. Upload Symbols Failed2. type UIApplication does not conform to protocol Launcher3. method does not override any method from its superclass 最后 前言 为了新的镜像功能升级了macOS 15和iOS 18,Xcode也不可避免的需…

鸿蒙Harmony应用开发,数据驾驶舱 项目结构搭建

对于一个项目而言,在拿到我们的开发任务后,我们最重要的就是技术的选型。选型定下来了之后我们便开始脚手架的搭建,然后开始撸代码,开搞. 首先我们需要对一些常见依赖库的引入 我们需要再oh-package.json5的dependencies节点下面…

Nginx泛域名 解析的匹配前缀绑定或转发到子目录

网站的目录结构为: # tree /home/wwwroot/landui.com /home/wwwroot/landui.com ├── bbs │ └── index.html └── www └── index.html 2 directories, 2 files /home/wwwroot/landui.com为nginx的安装目录下默认的存放源代码的路径。 bbs为论坛…

Android 开发高频面试题之——Flutter

Android开发高频面试题之——Java基础篇 flutter高频面试题记录 Flutter1. dart中的作用域与了解吗2. dart中. .. ...分别是什么意思?3. Dart 是不是单线程模型?如何运行的?4. Dart既然是单线程模型支持多线程吗?5. Future是什么6. Stream是什么7. Flutter 如何和原生交互…