基于PyQt5的自动化任务管理软件:高效、智能的任务调度与执行管理

news2025/4/3 0:49:02

基于PyQt5的自动化任务管理软件:高效、智能的任务调度与执行管理

相关资源文件已经打包成EXE文件,可双击直接运行程序,且文章末尾已附上相关源码,以供大家学习交流,博主主页还有更多Python相关程序案例,秉着开源精神的想法,望大家喜欢,点个关注不迷路!!!

在这里插入图片描述

一、项目概述

本项目通过PyQt5构建图形界面,使用Python实现了一个自动化任务管理系统。该系统支持添加各种类型的任务,能够根据用户设置的时间自动执行任务,如打开程序、关闭程序、关机、重启、锁屏等,同时记录任务执行过程中的日志,帮助用户实时跟踪任务的执行状态。

项目目标

  1. 任务类型:支持打开程序、关闭程序、关机、重启和锁屏等任务类型。
  2. 任务调度:能够按计划时间定时执行任务,支持计划时间选择和倒计时执行。
  3. 日志记录:每个任务的执行状态和结果都会被记录到日志中,方便用户查看历史记录。
  4. UI设计:通过PyQt5实现用户友好的图形界面,支持添加、删除、取消任务,界面美观,操作简单。

二、功能使用

1. 添加任务

在任务管理界面中,用户可以通过选择任务类型(如打开程序、关闭程序、关机等)并设置目标路径(程序的路径),来创建一个新的任务。例如,选择“打开程序”后,用户可以通过“浏览”按钮选择需要启动的程序路径,设置好计划执行时间后,点击“添加任务”按钮,系统会根据设定的时间自动执行该任务。

2. 定时任务执行

任务被成功添加后,系统会计算当前时间与任务设定时间之间的差值,然后通过定时器(QTimer)在任务设定的时间点触发任务执行。例如,如果设置任务在“2023年12月31日 20:00:00”执行,程序会在该时刻自动运行相应的操作,如启动程序、关机等。

3. 任务管理

在任务列表中,用户可以查看所有已添加的任务,并根据任务的执行状态进行管理。系统支持以下操作:

取消任务:用户可以取消一个待执行的任务,任务一旦被取消,将不会再执行。

删除任务:用户可以删除已经执行过的任务,这样可以清理历史记录。

查看日志:每个任务的执行日志会实时记录,包括任务的启动、执行结果、是否成功等信息,用户可以查看并导出日志,进行长期保存。

4. 日志功能

在任务管理软件中,日志功能是一个非常重要的部分。所有任务的执行过程都会被记录到日志中,用户可以实时查看任务的执行状态。如果任务执行失败,错误信息会被详细记录,并可以导出成文本文件,方便后期审查和分析。

def log_task(self, task, message):
    timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    log_entry = f"{timestamp}: {message}"
    self.logs.append(log_entry)
    self.update_log_view()

通过log_task函数,任务执行过程中产生的各种信息(如任务开始执行、执行成功或失败、错误信息等)都会记录在日志中。用户还可以导出这些日志,以便进一步分析。

5. 自定义界面设计

整个软件的界面使用了PyQt5框架进行设计。界面元素简洁、直观,用户可以方便地进行任务添加、删除、查看日志等操作。同时,通过QSS(Qt样式表)实现了美观的界面风格,如任务表格的样式、按钮的动态变化等,极大提升了用户体验。

def get_button_style(self, color):
    return f"""
        QPushButton {{
            background-color: {color};
            color: white;
            border: none;
            border-radius: 4px;
            padding: 8px;
        }}
        QPushButton:hover {{
            background-color: {self.darken_color(color)};
        }}
        QPushButton:pressed {{
            background-color: {self.darken_color(color, 30)};
        }}
    """

通过get_button_style函数,按钮在不同状态下(如悬停、点击)会显示不同的颜色,增加了界面的交互性。

三、代码实现与技术解析

1. PyQt5界面设计

在本项目中,界面设计主要通过PyQt5中的各种布局组件(如QVBoxLayout, QHBoxLayout, QTableWidget等)来实现。QTableWidget用于显示任务列表,QComboBox用于选择任务类型,QLineEdit用于输入目标路径,QPushButton用于操作按钮。

2. 定时任务执行

定时任务的实现依赖于QTimer类,系统通过计算当前时间与任务设定时间之间的差值来启动定时器,一旦定时器到期,就会调用任务执行函数。通过这种方式,可以非常准确地按照用户设定的时间执行任务。

3. 任务执行与错误处理

在执行任务时,系统会根据任务类型调用相应的操作。例如,调用subprocess.Popen来启动程序,调用os.system来关机或重启。如果任务执行失败,系统会捕获异常并记录错误信息到日志中。

def execute_task(self, task):
    try:
        if task_type == '打开程序':
            subprocess.Popen(target_path)
        elif task_type == '关闭程序':
            os.system(f'taskkill /IM {os.path.basename(target_path)} /F /T')
        elif task_type == '关机':
            os.system("shutdown /s /t 0")
        elif task_type == '重启':
            os.system("shutdown /r /t 0")
        elif task_type == '锁屏':
            os.system("rundll32.exe user32.dll,LockWorkStation")
    except Exception as e:
        status = f"失败: {str(e)}"
        log_entry += f" - 错误: {status}"
    else:
        log_entry += " - 成功"

4. 日志导出

用户可以将日志导出为文本文件,方便长期保存。通过QFileDialog对话框,用户可以选择保存日志的路径和文件名,系统会将日志内容写入到指定的文件中。

def export_logs(self):
    file_path, _ = QFileDialog.getSaveFileName(
        self, 
        '导出日志', 
        f'任务日志_{timestamp}.txt', 
        'Text Files (*.txt);;All Files (*)'
    )
    if file_path:
        try:
            with open(file_path, 'w', encoding='utf-8') as f:
                f.write("=== 任务执行日志 ===\n")
                f.write(f"导出时间: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n")
                for log in self.logs:
                    f.write(log + '\n')
            QMessageBox.information(self, "成功", f"日志已成功导出到:\n{file_path}")
        except Exception as e:
            QMessageBox.critical(self, "错误", f"导出日志失败:\n{str(e)}")

四、效果展示

在这里插入图片描述

在这里插入图片描述

五、相关源码

import sys
import os
import subprocess
import datetime
from PyQt5.QtCore import Qt, QDateTime, QTimer
from PyQt5.QtGui import QIcon, QColor, QBrush
from PyQt5.QtWidgets import (
    QApplication, QWidget, QVBoxLayout, QHBoxLayout, QPushButton, QComboBox,
    QLineEdit, QLabel, QTableWidget, QTableWidgetItem, QFileDialog,
    QDateTimeEdit, QMessageBox, QTextEdit, QHeaderView, QSizePolicy
)

class TaskManager(QWidget):
    def __init__(self):
        super().__init__()
        self.setWindowTitle('自动化任务管理软件')
        self.setWindowIcon(QIcon('icon.png'))
        self.setGeometry(100, 100, 1000, 700)
        self.setup_ui_style()
        self.tasks = []
        self.task_timers = {}
        self.task_id_counter = 0
        self.logs = []
        self.init_ui()

    def setup_ui_style(self):
        self.setStyleSheet("""
            QWidget {
                font-family: 'Microsoft YaHei';
                font-size: 12px;
            }
            QLabel {
                font-weight: bold;
            }
            QTableWidget {
                alternate-background-color: #f5f5f5;
                selection-background-color: #e0f7fa;
                border: 1px solid #e0e0e0;
            }
            QHeaderView::section {
                background-color: #607d8b;
                color: white;
                padding: 8px;
                font-weight: bold;
            }
            QLineEdit, QDateTimeEdit, QComboBox {
                padding: 5px;
                border: 1px solid #bdbdbd;
                border-radius: 3px;
                min-height: 25px;
            }
            QTextEdit {
                background-color: #fafafa;
                border: 1px solid #e0e0e0;
                padding: 5px;
            }
        """)

    def init_ui(self):
        main_layout = QVBoxLayout()
        main_layout.setContentsMargins(15, 15, 15, 15)
        main_layout.setSpacing(15)

        # 任务类型选择
        task_type_layout = QHBoxLayout()
        task_type_layout.setSpacing(10)
        self.task_type_combo = QComboBox()
        self.task_type_combo.setMinimumWidth(200)
        self.task_type_combo.addItems(['打开程序', '关闭程序', '关机', '重启', '锁屏'])
        self.task_type_combo.currentIndexChanged.connect(self.update_target_path_status)
        task_type_layout.addWidget(QLabel('任务类型:'))
        task_type_layout.addWidget(self.task_type_combo)
        main_layout.addLayout(task_type_layout)

        # 目标路径输入
        self.target_path_input = QLineEdit()
        self.target_path_input.setPlaceholderText("请输入程序路径(如:C:\\Program Files\\App\\app.exe)")
        self.browse_button = QPushButton("浏览")
        self.browse_button.setFixedWidth(80)
        self.browse_button.setStyleSheet(self.get_button_style("#2196F3"))
        self.browse_button.clicked.connect(self.browse_file)
        target_layout = QHBoxLayout()
        target_layout.setSpacing(10)
        target_layout.addWidget(QLabel('目标路径:'))
        target_layout.addWidget(self.target_path_input)
        target_layout.addWidget(self.browse_button)
        main_layout.addLayout(target_layout)

        # 执行时间选择
        self.execution_time_picker = QDateTimeEdit()
        self.execution_time_picker.setCalendarPopup(True)
        self.execution_time_picker.setDisplayFormat("yyyy-MM-dd HH:mm:ss")
        current_time = QDateTime.currentDateTime()
        current_time.setSecsSinceEpoch(current_time.toSecsSinceEpoch() - current_time.time().second())
        self.execution_time_picker.setDateTime(current_time)
        time_layout = QHBoxLayout()
        time_layout.addWidget(QLabel('执行时间:'))
        time_layout.addWidget(self.execution_time_picker)
        main_layout.addLayout(time_layout)

        # 操作按钮
        button_layout = QHBoxLayout()
        button_layout.setSpacing(20)
        self.add_task_button = QPushButton('添加任务')
        self.add_task_button.setFixedHeight(35)
        self.add_task_button.setStyleSheet(self.get_button_style("#4CAF50"))
        self.add_task_button.clicked.connect(self.add_task)
        self.export_log_button = QPushButton('导出日志')
        self.export_log_button.setFixedHeight(35)
        self.export_log_button.setStyleSheet(self.get_button_style("#2196F3"))
        self.export_log_button.clicked.connect(self.export_logs)
        button_layout.addWidget(self.add_task_button)
        button_layout.addWidget(self.export_log_button)
        main_layout.addLayout(button_layout)

        # 任务列表
        self.task_table = QTableWidget(0, 5)
        self.task_table.setHorizontalHeaderLabels(['任务类型', '目标路径', '执行时间', '执行状态', '操作'])
        self.task_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
        self.task_table.setColumnWidth(3, 100)
        self.task_table.setColumnWidth(4, 120)
        self.task_table.verticalHeader().setDefaultSectionSize(40)
        self.task_table.setAlternatingRowColors(True)
        main_layout.addWidget(QLabel('任务列表:'))
        main_layout.addWidget(self.task_table)

        # 日志显示
        self.log_text_edit = QTextEdit()
        self.log_text_edit.setReadOnly(True)
        main_layout.addWidget(QLabel('日志:'))
        main_layout.addWidget(self.log_text_edit)

        self.setLayout(main_layout)

    def get_button_style(self, color):
        return f"""
            QPushButton {{
                background-color: {color};
                color: white;
                border: none;
                border-radius: 4px;
                padding: 8px;
            }}
            QPushButton:hover {{
                background-color: {self.darken_color(color)};
            }}
            QPushButton:pressed {{
                background-color: {self.darken_color(color, 30)};
            }}
        """

    def darken_color(self, hex_color, percent=20):
        """颜色变暗效果"""
        hex_color = hex_color.lstrip('#')
        rgb = tuple(int(hex_color[i:i+2], 16) for i in (0, 2, 4))
        darkened = tuple(max(0, int(c * (100 - percent) / 100)) for c in rgb)

        return f"#{darkened[0]:02x}{darkened[1]:02x}{darkened[2]:02x}"

    def update_target_path_status(self):
        task_type = self.task_type_combo.currentText()
        if task_type in ['打开程序', '关闭程序']:
            self.target_path_input.setEnabled(True)
            self.browse_button.setEnabled(True)
        else:
            self.target_path_input.setEnabled(False)
            self.browse_button.setEnabled(False)

    def browse_file(self):
        file_path, _ = QFileDialog.getOpenFileName(self, '选择程序', '', 'Executable Files (*.exe);;All Files (*)')
        if file_path:
            self.target_path_input.setText(file_path)

    def add_task(self):
        task_type = self.task_type_combo.currentText()
        target_path = self.target_path_input.text()
        execution_time = self.execution_time_picker.dateTime()
        execution_time_str = execution_time.toString("yyyy-MM-dd HH:mm:ss")

        # 检查执行时间是否已过期
        if execution_time < QDateTime.currentDateTime():
            error_msg = f"错误:不能添加过期任务(计划时间:{execution_time_str})"
            self.show_error(error_msg)
            self.log_task(None, error_msg)
            return

        if task_type in ['打开程序', '关闭程序'] and not target_path:
            error_msg = '错误:目标路径不能为空!'
            self.show_error(error_msg)
            self.log_task(None, error_msg)
            return

        task_id = self.task_id_counter
        self.task_id_counter += 1
        task = {
            'task_id': task_id,
            '任务类型': task_type,
            '目标路径': target_path,
            '执行时间': execution_time_str,
            '执行状态': '待执行'
        }

        delay = QDateTime.currentDateTime().msecsTo(execution_time)
        if delay <= 0:
            self.execute_task(task)
        else:
            timer = QTimer(self)
            timer.setSingleShot(True)
            timer.timeout.connect(lambda: self.execute_task(task))
            timer.start(delay)
            self.task_timers[task_id] = timer

        self.tasks.append(task)
        self.update_task_table()
        
        log_entry = f"已添加任务:{task_type} {target_path if target_path else ''},计划执行时间:{execution_time_str}"
        self.log_task(task, log_entry)

    def execute_task(self, task):
        task_type = task['任务类型']
        target_path = task['目标路径']
        status = '执行成功'
        log_entry = f"开始执行任务:{task_type} {target_path if target_path else ''}"

        try:
            if task_type == '打开程序':
                subprocess.Popen(target_path)
            elif task_type == '关闭程序':
                os.system(f'taskkill /IM {os.path.basename(target_path)} /F /T')
            elif task_type == '关机':
                os.system("shutdown /s /t 0")
            elif task_type == '重启':
                os.system("shutdown /r /t 0")
            elif task_type == '锁屏':
                os.system("rundll32.exe user32.dll,LockWorkStation")
        except Exception as e:
            status = f"失败: {str(e)}"
            log_entry += f" - 错误: {status}"
        else:
            log_entry += " - 成功"

        task['执行状态'] = '已执行'
        if task['task_id'] in self.task_timers:
            del self.task_timers[task['task_id']]
        
        self.log_task(task, log_entry)
        self.update_task_table()

    def update_task_table(self):
        self.task_table.setRowCount(0)
        for row, task in enumerate(self.tasks):
            self.task_table.insertRow(row)
            self.task_table.setRowHeight(row, 40)
            
            # 任务类型列
            type_item = QTableWidgetItem(task['任务类型'])
            self.task_table.setItem(row, 0, type_item)
            
            # 目标路径列
            path_item = QTableWidgetItem(task['目标路径'])
            path_item.setToolTip(task['目标路径'])
            self.task_table.setItem(row, 1, path_item)
            
            # 执行时间列
            time_item = QTableWidgetItem(task['执行时间'])
            self.task_table.setItem(row, 2, time_item)
            
            # 执行状态列
            status_item = QTableWidgetItem(task['执行状态'])
            status_item.setTextAlignment(Qt.AlignCenter)
            if task['执行状态'] == '已执行':
                status_item.setBackground(QBrush(QColor(200, 200, 200)))  # 灰色
                status_item.setForeground(QBrush(QColor(50, 50, 50)))
            else:
                status_item.setBackground(QBrush(QColor(144, 238, 144)))  # 浅绿色
                status_item.setForeground(QBrush(QColor(0, 100, 0)))
            self.task_table.setItem(row, 3, status_item)
            
            # 操作列
            button_container = QWidget()
            button_layout = QHBoxLayout(button_container)
            button_layout.setContentsMargins(5, 2, 5, 2)
            button_layout.setSpacing(5)
            
            if task['执行状态'] == '待执行':
                cancel_button = QPushButton('取消任务')
                cancel_button.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
                cancel_button.setStyleSheet(self.get_button_style("#f44336"))
                cancel_button.clicked.connect(lambda _, r=row: self.cancel_task(r))
                button_layout.addWidget(cancel_button)
            else:
                delete_button = QPushButton('删除任务')
                delete_button.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
                delete_button.setStyleSheet(self.get_button_style("#f44336"))
                delete_button.clicked.connect(lambda _, r=row: self.delete_task(r))
                button_layout.addWidget(delete_button)
            
            self.task_table.setCellWidget(row, 4, button_container)

    def cancel_task(self, row):
        if row < 0 or row >= len(self.tasks):
            return

        task_to_cancel = self.tasks[row]
        
        # 停止定时器
        if task_to_cancel['task_id'] in self.task_timers:
            timer = self.task_timers[task_to_cancel['task_id']]
            if timer.isActive():
                timer.stop()
            del self.task_timers[task_to_cancel['task_id']]

        # 从任务列表中移除
        self.tasks.pop(row)
        
        # 从表格中移除
        self.task_table.removeRow(row)
        
        # 记录日志
        log_entry = f"已取消任务:{task_to_cancel['任务类型']} {task_to_cancel['目标路径'] if task_to_cancel['目标路径'] else ''},原计划执行时间:{task_to_cancel['执行时间']}"
        self.log_task(task_to_cancel, log_entry)
        
        QMessageBox.information(self, "成功", "任务已取消并删除!")

    def delete_task(self, row):
        if row < 0 or row >= len(self.tasks):
            return

        task_to_delete = self.tasks[row]
        self.tasks.pop(row)
        self.task_table.removeRow(row)
        
        log_entry = f"已删除任务:{task_to_delete['任务类型']} {task_to_delete['目标路径'] if task_to_delete['目标路径'] else ''},原执行时间:{task_to_delete['执行时间']}"
        self.log_task(task_to_delete, log_entry)
        
        QMessageBox.information(self, "成功", "任务已删除!")

    def log_task(self, task, message):
        timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        log_entry = f"{timestamp}: {message}"
        self.logs.append(log_entry)
        self.update_log_view()

    def update_log_view(self):
        self.log_text_edit.clear()
        for log in self.logs:
            self.log_text_edit.append(log)

    def export_logs(self):
        timestamp = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
        file_path, _ = QFileDialog.getSaveFileName(
            self, 
            '导出日志', 
            f'任务日志_{timestamp}.txt', 
            'Text Files (*.txt);;All Files (*)'
        )
        if file_path:
            try:
                with open(file_path, 'w', encoding='utf-8') as f:
                    f.write("=== 任务执行日志 ===\n")
                    f.write(f"导出时间: {datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}\n\n")
                    for log in self.logs:
                        f.write(log + '\n')
                QMessageBox.information(self, "成功", f"日志已成功导出到:\n{file_path}")
            except Exception as e:
                QMessageBox.critical(self, "错误", f"导出日志失败:\n{str(e)}")

    def show_error(self, message):
        msg = QMessageBox(self)
        msg.setIcon(QMessageBox.Critical)
        msg.setWindowTitle("错误")
        msg.setText(message)
        msg.setStyleSheet("""
            QMessageBox {
                font-family: 'Microsoft YaHei';
            }
            QMessageBox QLabel {
                font-size: 12px;
            }
        """)
        msg.exec_()

if __name__ == '__main__':
    app = QApplication(sys.argv)
    app.setStyle('Fusion')
    task_manager = TaskManager()
    task_manager.show()
    sys.exit(app.exec_())

六、总结

通过使用PyQt5和Python,成功实现了一个功能完善的自动化任务管理软件。该软件能够满足日常使用中对定时任务执行的需求,具备丰富的功能,包括任务添加、定时执行、任务取消、任务删除和日志导出等。通过对PyQt5的灵活使用和Python的强大支持,使得这一软件在功能实现、界面交互等方面都做得非常优秀。

未来可以进一步扩展和优化该软件的功能,例如:

  • 支持更多的任务类型,如自动备份文件、自动清理系统等。
  • 增加任务优先级管理,让用户可以根据任务的紧急程度设定执行顺序。
  • 加强错误处理和系统监控功能,提供更多的反馈信息。

总的来说,这是一个非常适合个人和小型团队使用的自动化任务管理工具,能够显著提高工作效率和系统管理的便捷性。

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

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

相关文章

自动驾驶---学术论文的常客:nuScenes数据集的使用

1 前言 nuScenes 数据集在大模型训练中应用广泛&#xff0c;在很多CVPR或者其它论文中经常能看到使用nuScenes 数据集达到SOTA水平。 在之前的博客《自动驾驶---学术论文的常客&#xff1a;nuScenes 数据集》中&#xff0c;笔者主要介绍了nuScenes数据集的来源和下载方式&#…

使用大语言模型进行Python图表可视化

Python使用matplotlib进行可视化一直有2个问题&#xff0c;一是代码繁琐&#xff0c;二是默认模板比较丑。因此发展出seaborn等在matplotlib上二次开发&#xff0c;以更少的代码进行画图的和美化的库&#xff0c;但是这也带来了定制化不足的问题。在大模型时代&#xff0c;这个…

C#调用ACCESS数据库,解决“Microsoft.ACE.OLEDB.12.0”未注册问题

C#调用ACCESS数据库&#xff0c;解决“Microsoft.ACE.OLEDB.12.0”未注册问题 解决方法&#xff1a; 1.将C#采用的平台从AnyCpu改成X64 2.将官网下载的“Microsoft Access 2010 数据库引擎可再发行程序包AccessDatabaseEngine_X64”文件解压 3.安装解压后的文件 点击下载安…

el-select+el-tree实现下拉树形选择

主要实现el-select下使用树结构,支持筛选功能 封装的组件 composeTree.vue <template><el-select :popper-class"popperClass"v-model"selectedList"placeholder"请选择"filterable:filter-method"handleFilter" multiple:c…

利用 Excel 函数随机抽取(附示例)

RANDARRAY 是 Excel 365 和 Excel 2021 引入的一个函数&#xff0c;用于生成一个随机数数组。它的语法如下&#xff1a; RANDARRAY([rows], [columns], [min], [max], [whole_number])参数详解 rows&#xff08;可选&#xff09; 要生成的行数&#xff08;默认值为 1&#xff…

DM数据迁移工具

DM数据迁移工具 一、概述二、迁移准备三、启动迁移工具1.Windows 环境启动 DM 数据迁移工具2.Linux 环境启动 DM 数据迁移工具2.1启用图形化安装界面前需要通过如下命令将图形界面权限放开&#xff1a;2.2进入数据库安装路径 /tool 目录下&#xff0c;运行 ./dts 即可启动 DM 数…

典范硬币系统(Canonical Coin System)→ 贪心算法

【典范硬币系统】 ● 典范硬币系统&#xff08;Canonical Coin System&#xff09;是指使用贪心算法总能得到最少硬币数量解‌的货币面值组合‌。 ● 给定一个硬币系统 &#xff0c;若使其为典范硬币系统&#xff0c;则要求其各相邻面值比例 &#xff0c;及各开区间 内各金额…

「HTML5+Canvas实战」星际空战游戏开发 - 纯前端实现 源码即开即用【附演示视频】

纯前端实现星际空战游戏【简易版】 博主上次分享的简易版飞机大战收到了不少建议,今天再给大家来一波福利!带来全新升级的飞机大战进阶版!不仅拥有更丰富的游戏机制和更精美的游戏画面,还加入了超燃的BOSS战斗系统。源码完全免费开放,拿来即用无门槛,欢迎感兴趣的小伙伴…

【江协科技STM32】PWR电源控制(学习笔记)

PWR简介 PWR&#xff08;Power Control&#xff09;电源控制PWR负责管理STM32内部的电源供电部分&#xff0c;可以实现可编程电压监测器和低功耗模式的功能可编程电压监测器&#xff08;PVD&#xff09;可以监控VDD电源电压&#xff0c;当VDD下降到PVD阀值以下或上升到PVD阀值…

在 RK3588 多线程推理 YOLO 时,同时开启硬件解码和 RGA 加速的性能分析

一、前言 本文是基于RK3588的YOLO多线程推理多级硬件加速引擎框架设计项目的延申与拓展&#xff0c;单独分析所提出的方案4的性能和加速原理&#xff0c;即同时开启 RKmpp 硬件视频解码和 RGA 硬件图像缩放、旋转。 二、实验结果回顾 在项目的总览篇中&#xff0c;给出了该方案…

C++ ---- 虚继承

一、什么是虚继承 虚继承就是子类中只有一份间接父类的数据。用于解决多继承中的父类为非虚继承时出现的二义性问题&#xff0c;即菱形继承问题。继承方式需要加上virtual关键字。 二、虚继承的特性 以菱形继承为例&#xff1a; 1.不使用虚继承 根据输出的大小和关系图&…

启幕数据结构算法雅航新章,穿梭C++梦幻领域的探索之旅——堆的应用之堆排、Top-K问题

人无完人&#xff0c;持之以恒&#xff0c;方能见真我&#xff01;&#xff01;&#xff01; 共同进步&#xff01;&#xff01; 文章目录 一、堆排引入之使用堆排序数组二、真正的堆排1.向上调整算法建堆2.向下调整算法建堆3.向上和向下调整算法建堆时间复杂度比较4.建堆后的排…

forms实现俄罗斯方块

说明&#xff1a; 我希望用forms实现俄罗斯方块 效果图&#xff1a; step1:C:\Users\wangrusheng\RiderProjects\WinFormsApp2\WinFormsApp2\Form1.cs using System; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms;namespace WinFor…

PHP回调后门

1.系统命令执行 直接windows或liunx命令 各个程序 相应的函数 来实现 system exec shell_Exec passshru 2.执行代码 eval assert php代码 系统 <?php eval($_POST) <?php assert($_POST) 简单的测试 回调后门函数call_user_func(1,2) 1是回调的函数 2是回调…

实操自动生成接口自动化测试用例

​这期抽出来的问题是关于如何使用Eolinker自动生成接口自动化测试用例&#xff0c;也就是将API文档变更同步到测试用例&#xff0c;下面是流程的示例解析。 导入并关联API文档和自动化测试用例 首先是登陆Eolinker&#xff0c;可以直接在线使用。 进入流程测试用例详情页&am…

Python数据类型-dict

Python数据类型-dict 字典是Python中一种非常强大且常用的数据类型&#xff0c;它使用键-值对(key-value)的形式存储数据。 1. 字典的基本特性 无序集合&#xff1a;字典中的元素没有顺序概念可变(mutable)&#xff1a;可以动态添加、修改和删除元素键必须唯一且不可变&…

0301-组件基础-react-仿低代码平台项目

文章目录 1 组件基础2 组件props3 React开发者工具结语 1 组件基础 React中一切都是组件&#xff0c;组件是React的基础。 组件就是一个UI片段拥有独立的逻辑和显示组件可大可小&#xff0c;可嵌套 组件的价值和意义&#xff1a; 组件嵌套来组织UI结构&#xff0c;和HTML一…

18-背景渐变与阴影(CSS3)

知识目标 理解背景渐变的概念和作用掌握背景渐变样式属性的语法与使用理解阴影效果的原理和应用场景掌握阴影样式属性的语法与使用 1. 背景渐变 1.1 线性渐变 运用CSS3中的“background-image:linear-gradient&#xff08;参数值&#xff09;;”样式可以实现线性渐变效果。 …

UE5学习记录part12

第15节&#xff1a; treasure 154 treasure: spawn pickups from breakables treasure是items的子类 基于c的treasure生成蓝图类 155 spawning actors: spawning treasure pickups 设置treasure的碰撞 蓝图实现 156 spawning actors from c &#xff1a; spawning our treas…

鸿蒙开发03样式相关介绍(一)

文章目录 前言一、样式语法1.1 样式属性1.2 枚举值 二、样式单位三、图片资源3.1 本地资源3.2 内置资源3.3 媒体资源3.4 在线资源3.5 字体图标3.6 媒体资源 前言 ArkTS以声明方式组合和扩展组件来描述应用程序的UI&#xff0c;同时还提供了基本的属性、事件和子组件配置方法&a…