记录一下瞎做的鼠标定时点击程序

本文记录了一款使用Python的PyQT库创建的鼠标定时点击程序。程序包含一个QT界面,通过Qtdesigner生成,设有开始、结束、暂停、恢复功能。在实现部分,通过线程进行鼠标定时点击,可以设置点击位置、循环次数和间隔时间。用户可以通过界面调整参数并观察实时进度。

代码包含两个文件,一个是用Qtdesigner的界面(mouseui.py),一个是实现鼠标定时点击的程序(mouse.py)。没学的太深,感觉还有非常多的上升空间。。。

目录

1.QT界面部分:

2.实现鼠标定时点击部分:

2.1鼠标点击线程类:

2.2主界面类:

3.mouse.py代码:


1.QT界面部分:

这一部分使用QTdesign生成的,做的挺随意的,看看就好。。 

具体的教程可以看:[ PyQt入门教程 ] Qt Designer工具的使用_Color Space的博客-CSDN博客_qtdesigner控件介绍使用教程

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'mouseui.ui'
#
# Created by: PyQt5 UI code generator 5.15.4
#
# 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.setWindowFlags(QtCore.Qt.WindowStaysOnTopHint)#设定窗口最上层
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.frame = QtWidgets.QFrame(self.centralwidget)
        self.frame.setGeometry(QtCore.QRect(10, 40, 261, 211))#前面是起始像素点,后面是长宽
        self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame.setObjectName("frame")
        self.label_2 = QtWidgets.QLabel(self.frame)
        self.label_2.setGeometry(QtCore.QRect(50, 160, 41, 16))
        self.label_2.setObjectName("label_2")
        self.print_x = QtWidgets.QTextBrowser(self.frame)
        self.print_x.setGeometry(QtCore.QRect(110, 50, 141, 61))
        self.print_x.setObjectName("print_x")
        self.label = QtWidgets.QLabel(self.frame)
        self.label.setGeometry(QtCore.QRect(50, 70, 41, 16))
        self.label.setObjectName("label")
        self.print_y = QtWidgets.QTextBrowser(self.frame)
        self.print_y.setGeometry(QtCore.QRect(110, 140, 141, 61))
        self.print_y.setObjectName("print_y")
        self.label_3 = QtWidgets.QLabel(self.frame)
        self.label_3.setGeometry(QtCore.QRect(20, 10, 250, 31))
        self.label_3.setObjectName("label_3")
        self.frame_2 = QtWidgets.QFrame(self.centralwidget)
        self.frame_2.setGeometry(QtCore.QRect(350, 80, 421, 400))
        self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
        self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
        self.frame_2.setObjectName("frame_2")
        self.start_button = QtWidgets.QPushButton(self.frame_2)
        self.start_button.setGeometry(QtCore.QRect(40, 310, 93, 28))
        self.start_button.setObjectName("start_button")

        self.label_4 = QtWidgets.QLabel(self.frame_2)
        self.label_4.setGeometry(QtCore.QRect(10, 50, 72, 20))
        self.label_4.setObjectName("label_4")

        self.stop_button = QtWidgets.QPushButton(self.frame_2)
        self.stop_button.setGeometry(QtCore.QRect(290, 310, 93, 28))
        self.stop_button.setObjectName("stop_button")
        self.pause_button = QtWidgets.QPushButton(self.frame_2)
        self.pause_button.setGeometry(QtCore.QRect(160, 310, 93, 28))
        self.pause_button.setObjectName("pause_button")

        self.resume_button = QtWidgets.QPushButton(self.frame_2)
        self.resume_button.setGeometry(QtCore.QRect(160, 350, 93, 28))
        self.resume_button.setObjectName("resume_button")

        self.label_5 = QtWidgets.QLabel(self.frame_2)
        self.label_5.setGeometry(QtCore.QRect(10, 170, 121, 31))
        self.label_5.setObjectName("label_5")
        self.iter_time = QtWidgets.QLineEdit(self.frame_2)
        self.iter_time.setGeometry(QtCore.QRect(10, 90, 113, 21))
        self.iter_time.setObjectName("iter_time")
        self.pause_time = QtWidgets.QLineEdit(self.frame_2)
        self.pause_time.setGeometry(QtCore.QRect(10, 220, 113, 21))
        self.pause_time.setObjectName("pause_time")

        self.iter_left = QtWidgets.QTextBrowser(self.centralwidget)
        self.iter_left.setGeometry(QtCore.QRect(60, 430, 201, 101))
        self.iter_left.setObjectName("iter_left")
        self.label_8 = QtWidgets.QLabel(self.centralwidget)
        self.label_8.setGeometry(QtCore.QRect(60, 410, 72, 15))
        self.label_8.setFrameShape(QtWidgets.QFrame.NoFrame)
        self.label_8.setObjectName("label_8")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 26))
        self.menubar.setObjectName("menubar")
        self.menu = QtWidgets.QMenu(self.menubar)
        self.menu.setObjectName("menu")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
        self.menubar.addAction(self.menu.menuAction())

        self.retranslateUi(MainWindow)
        self.start_button.clicked.connect(MainWindow.start)#绑定三个按键事件
        self.stop_button.clicked.connect(MainWindow.end)
        self.pause_button.clicked.connect(MainWindow.pause)
        self.resume_button.clicked.connect(MainWindow.resume)

        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.label_2.setText(_translate("MainWindow", "Y"))
        self.label.setText(_translate("MainWindow", "X"))
        self.label_3.setText(_translate("MainWindow", "按住鼠标左键,拖动到需要的位置"))
        self.start_button.setText(_translate("MainWindow", "开始"))

        self.label_4.setText(_translate("MainWindow", "点击次数"))

        self.stop_button.setText(_translate("MainWindow", "终止"))
        self.pause_button.setText(_translate("MainWindow", "暂停"))
        self.resume_button.setText(_translate("MainWindow", "恢复"))
        self.label_5.setText(_translate("MainWindow", "间隔时间(s)"))
        self.label_8.setText(_translate("MainWindow", "信息窗口"))
        self.menu.setTitle(_translate("MainWindow", "鼠标点击小程序"))

值得一提的是调整控件位置的参数,四个应该分别对应左上角xy坐标,以及控件长宽

self.start_button.setGeometry(QtCore.QRect(40, 310, 93, 28))#x, y, 长, 宽

2.实现鼠标定时点击部分:

大概的逻辑就是点击开始按键,触发一个事件,然后读取设定的鼠标位置、循环次数、间隔事件然后定时点击对应位置。为了看起来炫酷一点我用了一个线程来实现这个功能。

2.1鼠标点击线程类:

初始化部分,trigger负责发送剩余循环次数信息,finish负责发送线程终止信号

class mouse_thread(QObject):  # 线程1,继承object
    trigger = pyqtSignal(int)#绑定一个事件
    finished = pyqtSignal(int)#发送终止信号
    # 线程接收参数信号

    def __init__(self, x, y, iter_time, pause_time):
        super(mouse_thread, self).__init__()
        self.m = PyMouse()
        self.x = x
        self.y = y
        self.iter = iter_time
        self.flag = 0
        self.pause_time = pause_time
        # 以下这俩实现阻塞,原理后续整理
        self.mutex = QMutex()
        self.cond = QWaitCondition()

线程启动后运行部分,flag会随着主线程通信改变,实现暂停,继续等效果

    def run(self):
        self.mutex.lock()
        self.trigger.emit(0)
        i = 0
        while i < self.iter:  # 循环n次
            time.sleep(self.pause_time)  # 延时t秒
            if self.flag == 0:
                self.m.move(self.x, self.y)  # 鼠标移动至坐标(x,y)
                self.m.click(self.x, self.y)  # 鼠标点击坐标(x,y)
                self.trigger.emit(i+1)
                i = i + 1
            elif self.flag == 2:
                self.trigger.emit(self.iter)
                break
            elif self.flag == 1:
                self.cond.wait(self.mutex)
        self.mutex.unlock()
        self.finished.emit(1)

可在主线程中调用的函数,改变flag的数值实现暂停等

    def pause(self):
        self.flag = 1

    def resume(self):
        self.flag = 0
        self.cond.wakeAll()

    def stop(self):
        self.flag = 2
​

2.2主界面类:

在QT文件中,将按键绑定到对应函数,包括start、end、pause、resume四个按键对应函数。

start函数包含鼠标线程的定义,将新线程移入QTthread,trigger、finish信号绑定对应函数。

  def start(self):
        #self.text_edit.toPlainText()
        #x = int(self.cinx.text())#获取QLineEdit中的内容
        #y = int(self.ciny.text())
        self.iter = int(self.iter_time.text())#获取QLineEdit(iter)中的内容
        pause_time = int(self.pause_time.text())
        self.thread = QThread()
        #这里创建线程,且直接将之前拖动到的鼠标位置赋值
        self.mthread = mouse_thread(self.x, self.y, self.iter, pause_time)
        self.mthread.trigger.connect(self.show_time)  # 连接信号
        # 把实例化的线程用moveToThread移到QThread管理
        self.mthread.moveToThread(self.thread) 
        # 线程开始执行之前,从相关线程发射信号
        self.thread.started.connect(self.mthread.run)
        # 接收子线程信号发来的数据
        self.mthread.trigger.connect(self.show_time)
        # 线程执行完成关闭线程
        #ps:解决线程从来不退出问题,之前是thread.finished.connect,
        #不会进入对应函数,现在让mthread结束后发送信号,然后结束线程
        self.mthread.finished.connect(self.threadStop)
        self.thread.start()

    def end(self):
        self.mthread.stop()

    def pause(self):
        self.mthread.pause()
        self.iter_left.setText("已暂停,剩余:" + str(self.pause_left_time))

    def resume(self):
        self.iter_left.setText("恢复中")
        self.mthread.resume()

重载了mouseMoveEvent,使得按下鼠标拖动时能够显示当鼠标位置(并设定为最终循环时点击的位置)。

    def mouseMoveEvent(self, event):#重载鼠标移动函数
        a = self.m.position()
        self.print_x.setText(str(a[0]))
        self.print_y.setText(str(a[1]))
        self.x = a[0]
        self.y = a[1]
        #print("Mouse moved.")

show_time函数接收线程发来的消息,并显示在QT界面上,threadstop接收到finish的信息则退出线程:

    def show_time(self, val):
        self.iter_left.setText("iter left:"+str(self.iter - val))
        self.pause_left_time = self.iter - val

    def threadStop(self, val):
        # 退出线程
        self.thread.quit()
        #print("ok")

3.mouse.py代码:

from pymouse import PyMouse   #调用Pymouse模块
import time   #调用时间模块(考略到网站点击延时)
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys
from mouseui import Ui_MainWindow
from qtpy.QtCore import QObject, QThread



class mouse_thread(QObject):  # 线程1,继承object,科学
    trigger = pyqtSignal(int)#绑定一个事件
    finished = pyqtSignal(int)#发送终止信号
    # 线程接收参数信号

    def __init__(self, x, y, iter_time, pause_time):
        super(mouse_thread, self).__init__()
        self.m = PyMouse()
        self.x = x
        self.y = y
        self.iter = iter_time
        self.flag = 0
        self.pause_time = pause_time
        # 以下这俩实现阻塞,原理后续整理
        self.mutex = QMutex()
        self.cond = QWaitCondition()

    def run(self):
        self.mutex.lock()
        self.trigger.emit(0)
        i = 0
        while i < self.iter:  # 循环n次
            time.sleep(self.pause_time)  # 延时t秒
            if self.flag == 0:
                self.m.move(self.x, self.y)  # 鼠标移动至坐标(x,y)
                self.m.click(self.x, self.y)  # 鼠标点击坐标(x,y)
                self.trigger.emit(i+1)
                i = i + 1
            elif self.flag == 2:
                self.trigger.emit(self.iter)
                break
            elif self.flag == 1:
                self.cond.wait(self.mutex)
        self.mutex.unlock()
        self.finished.emit(1)

    def pause(self):
        self.flag = 1

    def resume(self):
        self.flag = 0
        self.cond.wakeAll()

    def stop(self):
        self.flag = 2


class MyMainForm(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MyMainForm, self).__init__(parent)
        self.setupUi(self)
        self.m = PyMouse()
        self.iter = 0
        self.x = 0
        self.y = 0
        self.pause_left_time = 0
        #self.centralwidget.setMouseTracking(True)#不设置的话必须鼠标按住才能追踪
        #self.setMouseTracking(True)#不设置的话必须鼠标按住才能追踪

    def start(self):
        #self.text_edit.toPlainText()
        #x = int(self.cinx.text())#获取QLineEdit中的内容
        #y = int(self.ciny.text())
        self.iter = int(self.iter_time.text())#获取QLineEdit(iter)中的内容
        pause_time = int(self.pause_time.text())
        self.thread = QThread()
        #这里创建线程,且直接将之前拖动到的鼠标位置赋值
        self.mthread = mouse_thread(self.x, self.y, self.iter, pause_time)
        self.mthread.trigger.connect(self.show_time)  # 连接信号
        # 把实例化的线程用moveToThread移到QThread管理
        self.mthread.moveToThread(self.thread)
        # 线程开始执行之前,从相关线程发射信号
        self.thread.started.connect(self.mthread.run)
        # 接收子线程信号发来的数据
        self.mthread.trigger.connect(self.show_time)
        # 线程执行完成关闭线程
        self.mthread.finished.connect(self.threadStop)
        self.thread.start()

    def end(self):
        self.mthread.stop()

    def pause(self):
        self.mthread.pause()
        self.iter_left.setText("已暂停,剩余:" + str(self.pause_left_time))

    def resume(self):
        self.iter_left.setText("恢复中")
        self.mthread.resume()

    def mouseMoveEvent(self, event):#重载鼠标移动函数
        a = self.m.position()
        self.print_x.setText(str(a[0]))
        self.print_y.setText(str(a[1]))
        self.x = a[0]
        self.y = a[1]
        #print("Mouse moved.")

    def show_time(self, val):
        self.iter_left.setText("iter left:"+str(self.iter - val))
        self.pause_left_time = self.iter - val

    def threadStop(self, val):
        # 退出线程
        self.thread.quit()
        #print("ok")


if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = MyMainForm()
    demo.show()
    sys.exit(app.exec_())



 

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值