使用Python开发测试小工具-录制回放工具的实现
生活随笔
收集整理的這篇文章主要介紹了
使用Python开发测试小工具-录制回放工具的实现
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
Pyqt5 信號槽機制可參考:https://blog.51cto.com/9291927/2422187
信號槽是Qt的核心機制,也是PyQt編程中對象進行通信的機制。在Qt中,QObject對象和PyQt中所有繼承自QWidget的控件都支持信號槽機制。當(dāng)信號發(fā)射時,連接的槽函數(shù)會自動執(zhí)行。在PyQt5中,信號與槽函數(shù)通過object.signal.connect()方法進行連接。
mymainwindow.py? 通過QtDesigner設(shè)計并轉(zhuǎn)換
from PyQt5 import QtCore, QtGui, QtWidgetsclass Ui_MainWindow(object):def setupUi(self, MainWindow):MainWindow.setObjectName("MainWindow")MainWindow.resize(800, 600)self.centralwidget = QtWidgets.QWidget(MainWindow)self.centralwidget.setObjectName("centralwidget")self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.centralwidget)self.horizontalLayout_2.setObjectName("horizontalLayout_2")self.verticalLayout = QtWidgets.QVBoxLayout()self.verticalLayout.setObjectName("verticalLayout")self.horizontalLayout = QtWidgets.QHBoxLayout()self.horizontalLayout.setObjectName("horizontalLayout")self.pushButton_1 = QtWidgets.QPushButton(self.centralwidget)self.pushButton_1.setObjectName("pushButton_1")self.horizontalLayout.addWidget(self.pushButton_1)self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)self.pushButton_2.setObjectName("pushButton_2")self.horizontalLayout.addWidget(self.pushButton_2)self.line = QtWidgets.QFrame(self.centralwidget)self.line.setFrameShape(QtWidgets.QFrame.VLine)self.line.setFrameShadow(QtWidgets.QFrame.Sunken)self.line.setObjectName("line")self.horizontalLayout.addWidget(self.line)self.pushButton_3 = QtWidgets.QPushButton(self.centralwidget)self.pushButton_3.setObjectName("pushButton_3")self.horizontalLayout.addWidget(self.pushButton_3)self.pushButton_4 = QtWidgets.QPushButton(self.centralwidget)self.pushButton_4.setObjectName("pushButton_4")self.horizontalLayout.addWidget(self.pushButton_4)self.verticalLayout.addLayout(self.horizontalLayout)self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)self.tableWidget.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)self.tableWidget.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)self.tableWidget.setObjectName("tableWidget")self.tableWidget.setColumnCount(0)self.tableWidget.setRowCount(0)self.tableWidget.horizontalHeader().setCascadingSectionResizes(False)self.tableWidget.verticalHeader().setVisible(False)self.verticalLayout.addWidget(self.tableWidget)self.horizontalLayout_2.addLayout(self.verticalLayout)MainWindow.setCentralWidget(self.centralwidget)self.menubar = QtWidgets.QMenuBar(MainWindow)self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 23))self.menubar.setObjectName("menubar")MainWindow.setMenuBar(self.menubar)self.statusbar = QtWidgets.QStatusBar(MainWindow)self.statusbar.setObjectName("statusbar")MainWindow.setStatusBar(self.statusbar)self.retranslateUi(MainWindow)QtCore.QMetaObject.connectSlotsByName(MainWindow)def retranslateUi(self, MainWindow):_translate = QtCore.QCoreApplication.translateMainWindow.setWindowTitle(_translate("MainWindow", "按鍵精靈"))self.pushButton_1.setText(_translate("MainWindow", "錄制"))self.pushButton_2.setText(_translate("MainWindow", "停止"))self.pushButton_3.setText(_translate("MainWindow", "回放"))self.pushButton_4.setText(_translate("MainWindow", "停止"))self.tableWidget.setSortingEnabled(True)mylistener.py 文件,定義MyWindow類,繼承自Ui_MainWindow,并在其中定義信號與槽
import sys import os import threading import time from PyQt5.QtCore import Qt from PyQt5.QtWidgets import QApplication, QMainWindow, QCheckBox, QTableWidgetItem from mymainwindow import * from pynput import mouse, keyboard from record import Recorder from playback import PlayBack import ctypesclass MyWindow(QMainWindow, Ui_MainWindow):def __init__(self, parent=None):super(MyWindow, self).__init__(parent)self.setupUi(self)self.inittable()self.getscripts()self.pushButton_1.clicked.connect(self.start_record)self.pushButton_2.clicked.connect(self.getscripts)self.pushButton_2.clicked.connect(self.stop_record)self.pushButton_3.clicked.connect(self.start_playback)self.pushButton_4.clicked.connect(self.stop_playback)#self.pushButton_4.clicked.connect(self.reset_button)self.__mouse_thread: mouse.Listener = Noneself.__key_thread: keyboard.Listener = Noneself.__playback_thread: PlayBack = Nonedef start_record(self):self.setWindowState(Qt.WindowMinimized)self.pushButton_1.setDisabled(True)self.pushButton_3.setDisabled(True)self.pushButton_4.setDisabled(True)filename = time.strftime("%Y_%m_%d_%H_%M_%S_", time.localtime(time.time())) + "Record.txt"file = os.path.join(os.getcwd(), filename)mylistener = Recorder(file)self.__mouse_thread = mouse.Listener(on_click=mylistener.on_click)self.__key_thread = keyboard.Listener(on_press=mylistener.on_press, on_release=mylistener.on_release)self.__mouse_thread.start()self.__key_thread.start()def stop_record(self):if self.__mouse_thread is not None:if self.__mouse_thread.isAlive():self.__mouse_thread.stop()if self.__mouse_thread is not None:if self.__key_thread.isAlive():self.__key_thread.stop()self.pushButton_1.setDisabled(False)self.pushButton_3.setDisabled(False)self.pushButton_4.setDisabled(False)def inittable(self):# 設(shè)置行數(shù)和列數(shù)self.tableWidget.setColumnCount(3)self.tableWidget.setRowCount(1)self.tableWidget.setColumnWidth(0, 100)self.tableWidget.setColumnWidth(1, 300)self.tableWidget.setColumnWidth(2, 300)# 設(shè)置數(shù)據(jù)標(biāo)題self.tableWidget.horizontalHeader().setStyleSheet("QHeaderView::section{background:skyblue;}")self.tableWidget.setHorizontalHeaderItem(0, QTableWidgetItem("序號"))self.tableWidget.setHorizontalHeaderItem(1, QTableWidgetItem("文件名"))self.tableWidget.setHorizontalHeaderItem(2, QTableWidgetItem("修改時間"))self.tableWidget.horizontalHeader().setStretchLastSection(True)def getscripts(self):# 獲取當(dāng)前路徑下的txt文件cwdpath = os.getcwd()filelist = []for file in os.listdir(cwdpath):if file.endswith(".txt"):filelist.append(file)row_num = len(filelist)self.tableWidget.setRowCount(row_num)# 設(shè)置數(shù)據(jù)條目for row in range(row_num):# 第一列為checkboxitem_checked = QTableWidgetItem()item_checked.setText(str(row + 1))item_checked.setCheckState(Qt.Unchecked)item_checked.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)self.tableWidget.setItem(row, 0, item_checked)# 第二列為文件名item_name = QTableWidgetItem(filelist[row])item_name.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)self.tableWidget.setItem(row, 1, item_name)# 第三列為文件修改時間filepath = os.path.join(cwdpath, filelist[row])mtime = os.stat(filepath).st_mtimemtime_str = time.strftime('%Y_%m_%d %H:%M:%S', time.localtime(mtime))item_time = QTableWidgetItem(mtime_str)item_time.setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)self.tableWidget.setItem(row, 2, item_time)def get_checkedfiles(self):rownum = self.tableWidget.rowCount()filelist = []for i in range(rownum):if self.tableWidget.item(i, 0).checkState() == Qt.Checked:filename = self.tableWidget.item(i, 1).text()file = os.path.join(os.getcwd(), filename)filelist.append(file)return filelistdef start_playback(self):filelist = self.get_checkedfiles()if len(filelist) != 0:self.setWindowState(Qt.WindowMinimized)self.pushButton_1.setDisabled(True)self.pushButton_2.setDisabled(True)self.pushButton_3.setDisabled(True)self.__playback_thread = PlayBack(filelist)self.__playback_thread.start()self.__playback_thread.finished.connect(self.reset_button)def reset_button(self):self.pushButton_1.setDisabled(False)self.pushButton_2.setDisabled(False)self.pushButton_3.setDisabled(False)self.pushButton_4.setDisabled(False)def stop_playback(self):if self.__playback_thread is not None:if self.__playback_thread.isRunning():self.__playback_thread.stop()if __name__ == '__main__':app = QApplication(sys.argv)myWin = MyWindow()myWin.show()sys.exit(app.exec_())record.py 啟動線程對鼠標(biāo)鍵盤進行監(jiān)控
import os import time from pynput import mouse from pynput.mouse import Button from pynput import keyboard from _datetime import datetimeclass Recorder(object):def __init__(self, file):self.file = filedef on_click(self, x, y, button, pressed):if button == Button.left:button_name = 'Left'elif button == Button.middle:button_name = 'Middle'elif button == Button.right:button_name = 'Right'else:button_name = 'Unknown'if pressed:msg = 'mouse {0} Presses at {1} {2} \n'.format(button_name, x, y)else:msg = 'mouse {0} Released at {1} {2} \n'.format(button_name, x, y)with open(self.file, "a") as f:timestr = datetime.now().strftime("%Y_%m_%d_%H_%M_%S.%f")[:-3]f.write(timestr)f.write(" ")f.write(msg)def on_press(self, key):# msg = 'key {0} pressed \n'.format(key)try:msg = 'key alphanumeric {0} pressed \n'.format(key.char)except AttributeError:msg = 'key special {0} pressed \n'.format(key)with open(self.file, "a") as f:timestr = datetime.now().strftime("%Y_%m_%d_%H_%M_%S.%f")[:-3]f.write(timestr)f.write(" ")f.write(msg)def on_release(self, key):# msg = 'key {0} released \n'.format(key)try:msg = 'key alphanumeric {0} released \n'.format(key.char)except AttributeError:msg = 'key special {0} released \n'.format(key)# Stop listenerif key == keyboard.Key.esc:return Falsewith open(self.file, "a") as f:timestr = datetime.now().strftime("%Y_%m_%d_%H_%M_%S.%f")[:-3]f.write(timestr)f.write(" ")f.write(msg)playback.py 對錄制文件進行解析,并回放
import ctypes import re from _datetime import datetime import timefrom PyQt5.QtCore import QThread, pyqtSignal from PyQt5.QtWidgets import QMainWindow from pynput.mouse import Button, Controller as MController from pynput.keyboard import Key, Controller as KController import threadingfrom mymainwindow import Ui_MainWindowclass PlayBack(QThread):# trigger = pyqtSignal()def __init__(self, filelist):super(PlayBack, self).__init__()self.filelist = filelistself._running = Truedef run(self):time.sleep(3)self.playback_allfiles()# self.trigger.emit()def stop(self):self._running = Falsedef playback_allfiles(self):for file in self.filelist:self.playback_file(file)def playback_file(self, file):with open(file, "r") as f:timestmpA = 0for line in f:if self._running:if timestmpA != 0:timeB = datetime.strptime(line.split(" ")[0], "%Y_%m_%d_%H_%M_%S.%f")timestmpB = timeB.timestamp()timedelta = timestmpB - timestmpAtime.sleep(timedelta)if "mouse" in line:# print("This is the mouse operation")pattern = re.compile(r"(\d+) (\d+)")match = re.search(pattern, line)if match:x = match.group(1)y = match.group(2)mouse = MController()mouse.position = (x, y)if "Presses" in line:if "Left" in line:mouse.press(button=Button.left)print("Mouse Left press at ({0},{1})".format(x, y))elif "Right" in line:mouse.click(button=Button.right)print("Mouse Right press at ({0},{1})".format(x, y))elif "Middle" == line:mouse.click(button=Button.middle)print("Mouse Middle press at ({0},{1})".format(x, y))else:print("Unkonwn Mouse Action")elif "Released" in line:if "Left" in line:mouse.release(button=Button.left)print("Mouse Left release at ({0},{1})".format(x, y))elif "Right" in line:mouse.release(button=Button.right)print("Mouse Right release at ({0},{1})".format(x, y))elif "Middle" == line:mouse.release(button=Button.middle)print("Mouse Middle release at ({0},{1})".format(x, y))else:print("Unkonwn Mouse Action")else:print("Error:There is no mouse position")elif "key" in line:# print("This is the keyboard operation")keyboard = KController()if "special" in line:pattern = re.compile(r"special (.+?) ")match = re.search(pattern, line)if match:key = eval(match.group(1))else:print("Error:There is no key action")elif "alphanumeric" in line:pattern = re.compile(r"alphanumeric (.+?) ")match = re.search(pattern, line)if match:key = match.group(1)else:print("Error:There is no key action")if "pressed" in line:keyboard.press(key)print("Keyboard pressed {0}".format(key))elif "released" in line:keyboard.release(key)print("Keyboard released {0}".format(key))timeA = datetime.strptime(line.split(" ")[0], "%Y_%m_%d_%H_%M_%S.%f")timestmpA = timeA.timestamp()else:break實際效果如圖
總結(jié)
以上是生活随笔為你收集整理的使用Python开发测试小工具-录制回放工具的实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: springboot视图解析器配置
- 下一篇: ApkToolkit安卓反编译工具(超级