"""
This module provides functionality for screen recording and updating labels.
Classes:
Worker: Worker class responsible for screen recording and updating labels.
UpdaterImage: Class for updating images.
Attributes:
None
"""
import os
from datetime import datetime
from PyQt6.QtCore import pyqtSignal, QObject, QTimer, QThread
from PyQt6 import QtWidgets
import cv2
import numpy as np
[docs]
class Worker(QObject):
"""
Worker class responsible for screen recording and updating labels.
Attributes:
get_image (pyqtSignal): Signal for sending images.
Methods:
__init__: Initialize the Worker.
initialize_record_screen: Initializes the screen recording.
record_state: Getter and setter methods for the recording state.
get_event: Stores the given event position.
update_label: Updates the label with the current screen image.
qt_pixmap_to_cv_img: Converts a QPixmap object to a numpy array.
main: The main function of the Worker class.
"""
get_image = pyqtSignal(object)
[docs]
def __init__(self):
"""
Initialize the Worker.
This method initializes the Worker class with default values for its attributes.
It also grabs the primary screen and sets the size of the recording window.
"""
super().__init__()
self.out = None
self.event = None
self.timer = None
self.__record = False
index = QtWidgets.QApplication.primaryScreen().grabWindow()
try:
image = self.qt_pixmap_to_cv_img(index)
self.size_wind = (image.shape[1], image.shape[0])
except AttributeError as e:
# Handle specific exception, for example, if qt_pixmap_to_cv_img is not implemented
print(f"AttributeError: {e}")
except TypeError as e:
# Handle specific exception, for example, if index is not valid for qt_pixmap_to_cv_img
print(f"TypeError: {e}")
except Exception as e:
# Catch any other exception and log it
print(f"An unexpected error occurred: {e}")
_time = datetime.now()
self._time = _time.strftime("record_%H_%M_%S")
[docs]
def initialize_record_screen(self):
"""
Initializes the screen recording by creating a VideoWriter object.
If the VideoWriter object has not been created yet, this function creates it and sets the output video file path and codec.
If the directory to store the recorded file does not exist, it will create it.
"""
if self.out is None:
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
path_file = os.path.normpath(os.getcwd() + os.sep + os.pardir)
dst_directory = path_file + "/file_recorded/"
if not os.path.isdir(dst_directory):
os.makedirs(os.path.dirname(dst_directory))
file_record = dst_directory + self._time + ".avi"
self.out = cv2.VideoWriter(file_record, fourcc, 10.0, self.size_wind)
@property
def record_state(self):
"""
A getter method for the private variable __record.
Returns:
bool: The current state of the recording (True for active, False for inactive).
"""
return self.__record
@record_state.setter
def record_state(self, state):
"""
A setter method for the private variable __record.
Args:
state (bool): The state to set the recording to (True for active, False for inactive).
"""
self.__record = state
[docs]
def get_event(self, event):
"""
Stores the given event position.
Args:
event (QPoint): The QPoint object containing the event position.
"""
self.event = event
[docs]
def update_label(self):
"""
Updates the label with the current screen image.
If recording is active, it writes the current screen image to the output video file.
"""
if self.event is not None:
index = QtWidgets.QApplication.screenAt(self.event)
if index is not None:
index = index.grabWindow()
image = self.qt_pixmap_to_cv_img(index)
if self.record_state:
self.out.write(image)
[docs]
@classmethod
def qt_pixmap_to_cv_img(cls, qt_pixmap):
"""
Converts a QPixmap object to a numpy array.
Args:
qt_pixmap (QPixmap): The QPixmap object to convert.
Returns:
numpy.ndarray: The converted image as a numpy array.
"""
q_img = qt_pixmap.toImage()
temp_shape = (q_img.height(), q_img.bytesPerLine() * 8 // q_img.depth())
temp_shape += (4,)
ptr = q_img.bits()
ptr.setsize(q_img.bytesPerLine() * q_img.height())
result = np.array(ptr, dtype=np.uint8).reshape(temp_shape)
result = result[..., :3]
return result
[docs]
def main(self):
"""
The main function of the VideoRecorder class.
Initializes the QTimer object and sets the interval to 1/30 of a second.
Connects the QTimer object to the update_label function.
"""
self.timer = QTimer()
self.timer.setInterval(int(1000 / 10))
self.timer.timeout.connect(self.update_label)
[docs]
class UpdaterImage:
"""
Class responsible for updating images.
Attributes:
thread (QThread): The thread for running the worker.
worker (Worker): The worker responsible for image updating.
Methods:
__init__: Initializes the UpdaterImage.
"""
[docs]
def __init__(self):
self.thread = QThread()
self.worker = Worker()
self.worker.moveToThread(self.thread)
self.thread.started.connect(self.worker.update_label)