【Python 开源】你的 Windows 关机助手——PyQt5 版定时关机工具

🖥️ 你的 Windows 关机助手——PyQt5 版定时关机工具

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

📌 概述

在日常使用电脑的过程中,我们经常会遇到需要定时关机的场景,比如:

  • 夜间下载文件,想让电脑在任务完成后自动关机。
  • 长时间运行的程序,需要在某个时间点关闭系统。
  • 限制电脑使用时间,避免长时间占用资源。

虽然 Windows 自带 shutdown 命令可以定时关机,但操作方式较为繁琐,缺乏可视化界面。因此,本篇文章将带大家实现一个基于 PyQt5 的 Windows 定时关机工具,支持定时或延时关机、重启、注销,并提供系统托盘功能,方便随时管理关机任务。
在这里插入图片描述

🎯 功能介绍

本工具主要具备以下功能:

定时关机 —— 设定具体时间,到点自动关机。

延时关机 —— 设置倒计时,倒计时结束后自动关机。

重启 & 注销 —— 除关机外,还可执行系统重启和注销操作。

取消操作 —— 关机前可随时取消,避免误操作。

系统托盘支持 —— 运行后最小化到系统托盘,不影响日常操作。

人性化提示 —— 关机前弹出提醒,避免突发关机。

🔧 代码实现

📌 1. 安装依赖

在运行代码之前,我们需要先安装 PyQt5 库:

pip install PyQt5 pyqt5-tools

📌 2. 代码编写

以下是完整的代码实现:

import sys
import os
import time
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QPushButton, QVBoxLayout, QTimeEdit, QSystemTrayIcon, QMenu, QAction
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import QTimer, QTimeclass ShutdownApp(QWidget):def __init__(self):super().__init__()self.initUI()def initUI(self):self.setWindowTitle('Windows 定时关机工具')self.setGeometry(600, 300, 300, 200)self.label = QLabel('请选择关机时间:', self)self.timeEdit = QTimeEdit(self)self.timeEdit.setDisplayFormat("HH:mm")self.startButton = QPushButton('设置关机', self)self.startButton.clicked.connect(self.scheduleShutdown)self.cancelButton = QPushButton('取消关机', self)self.cancelButton.clicked.connect(self.cancelShutdown)layout = QVBoxLayout()layout.addWidget(self.label)layout.addWidget(self.timeEdit)layout.addWidget(self.startButton)layout.addWidget(self.cancelButton)self.setLayout(layout)# 托盘功能self.trayIcon = QSystemTrayIcon(QIcon("icon.png"), self)trayMenu = QMenu()exitAction = QAction("退出", self)exitAction.triggered.connect(self.close)trayMenu.addAction(exitAction)self.trayIcon.setContextMenu(trayMenu)self.trayIcon.show()def scheduleShutdown(self):shutdown_time = self.timeEdit.time()current_time = QTime.currentTime()seconds = current_time.secsTo(shutdown_time)if seconds <= 0:self.label.setText("请选择一个未来的时间!")returnself.label.setText(f"关机已设置,将在 {shutdown_time.toString()} 执行")os.system(f'shutdown -s -t {seconds}')def cancelShutdown(self):os.system('shutdown -a')self.label.setText("关机已取消!")if __name__ == '__main__':app = QApplication(sys.argv)ex = ShutdownApp()ex.show()sys.exit(app.exec_())

📌 功能使用

🛠️ 1. 运行软件

python shutdown_tool.py

⏳ 2. 设置定时关机

  • 选择时间
  • 点击 “设置关机”
  • 程序将计算剩余时间,并执行关机命令

🚫 3. 取消关机

  • 如果想取消定时关机,点击 “取消关机” 按钮

  • 也可以手动在命令行执行:

    shutdown -a
    

🔽 4. 系统托盘

  • 运行后可最小化到托盘
  • 右键点击托盘图标可 退出应用

📊 技术要点解析

1️⃣ 关机命令

Windows 提供 shutdown 命令来执行关机任务:

  • 定时关机

    shutdown -s -t 秒数
    
  • 取消关机

    shutdown -a
    

2️⃣ 计算关机时间

我们使用 QTime 计算当前时间到设定时间的 秒数,避免时间计算错误:

seconds = current_time.secsTo(shutdown_time)

3️⃣ 托盘图标支持

使用 QSystemTrayIcon 实现最小化到托盘:

self.trayIcon = QSystemTrayIcon(QIcon("icon.png"), self)

这样即使窗口关闭,应用仍能在后台运行。

运行效果

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

相关源码

import os
import sys
import time
import configparser
import win32api
import win32con
from datetime import datetime, timedelta
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, QGroupBox, QRadioButton, QDateTimeEdit, QLabel, QPushButton, QCheckBox, QSystemTrayIcon, QMenu, QMessageBox, QSpacerItem, QSizePolicy, QFrame)
from PyQt5.QtCore import Qt, QTimer, QDateTime, QTime, QSize, QSharedMemory
from PyQt5.QtGui import QIcon, QFont, QPalette, QColordef resource_path(relative_path):""" 获取资源的绝对路径,适用于开发环境和PyInstaller单文件模式 """if hasattr(sys, '_MEIPASS'):# PyInstaller创建的临时文件夹return os.path.join(sys._MEIPASS, relative_path)return os.path.join(os.path.abspath('.'), relative_path)class ShutdownApp(QMainWindow):def __init__(self):super().__init__()self.task_running = Falseself.config_file = os.path.join(os.getenv('APPDATA'), 'shutdown_config.ini')self.first_show = True  # 用于跟踪是否是第一次显示self.setup_ui_style()self.init_ui()self.load_config()# 系统托盘self.tray_icon = QSystemTrayIcon(self)self.tray_icon.setIcon(QIcon(resource_path("icon.ico")))self.tray_icon.setToolTip("定时关机")self.tray_icon.activated.connect(self.tray_icon_activated)# 托盘菜单self.tray_menu = QMenu()self.show_action = self.tray_menu.addAction("显示")self.exit_action = self.tray_menu.addAction("退出")self.show_action.triggered.connect(self.show_normal)self.exit_action.triggered.connect(self.confirm_exit)self.tray_icon.setContextMenu(self.tray_menu)self.tray_icon.show()  # 确保托盘图标显示# 显示当前时间self.timer = QTimer(self)self.timer.timeout.connect(self.update_current_time)self.timer.start(1000)# 剩余时间计时器self.countdown_timer = QTimer(self)self.countdown_timer.timeout.connect(self.update_remaining_time)def setup_ui_style(self):"""设置全局UI样式"""self.setStyleSheet("""QMainWindow {background-color: #f5f5f5;}QGroupBox {border: 1px solid #ccc;border-radius: 4px;margin-top: 10px;padding-top: 15px;font-weight: bold;color: #333;}QGroupBox::title {subcontrol-origin: margin;left: 10px;padding: 0 3px;}QRadioButton, QCheckBox {color: #444;}QPushButton {background-color: #4CAF50;color: white;border: none;padding: 8px 16px;border-radius: 4px;min-width: 80px;}QPushButton:hover {background-color: #45a049;}QPushButton:disabled {background-color: #cccccc;}QPushButton#cancel_btn {background-color: #f44336;}QPushButton#cancel_btn:hover {background-color: #d32f2f;}QDateTimeEdit {padding: 5px;border: 1px solid #ddd;border-radius: 4px;}QLabel#current_time_label {font-size: 16px;color: #333;padding: 5px;background-color: #e9f5e9;border-radius: 4px;}QLabel#remaining_time_label {font-size: 16px;color: #d32f2f;font-weight: bold;padding: 5px;background-color: #f9e9e9;border-radius: 4px;}""")def init_ui(self):self.setWindowTitle("定时关机")self.setWindowIcon(QIcon(resource_path("icon.ico")))self.resize(300, 440)# 主窗口布局main_widget = QWidget()self.setCentralWidget(main_widget)layout = QVBoxLayout(main_widget)layout.setContentsMargins(12, 12, 12, 12)layout.setSpacing(10)# 当前时间显示self.current_time_label = QLabel()self.current_time_label.setAlignment(Qt.AlignCenter)self.current_time_label.setObjectName("current_time_label")layout.addWidget(self.current_time_label)# 添加分隔线line = QFrame()line.setFrameShape(QFrame.HLine)line.setFrameShadow(QFrame.Sunken)layout.addWidget(line)# 定时/延时选择time_type_group = QGroupBox("时间类型")time_type_layout = QHBoxLayout()time_type_layout.setContentsMargins(10, 15, 10, 10)self.fixed_time_radio = QRadioButton("定时关机")self.delay_time_radio = QRadioButton("延时关机")self.fixed_time_radio.setChecked(True)time_type_layout.addWidget(self.fixed_time_radio)time_type_layout.addWidget(self.delay_time_radio)time_type_group.setLayout(time_type_layout)layout.addWidget(time_type_group)# 定时时间选择self.fixed_datetime = QDateTimeEdit()self.fixed_datetime.setDisplayFormat("yyyy-MM-dd HH:mm:ss")self.fixed_datetime.setDateTime(QDateTime.currentDateTime())self.fixed_datetime.setCalendarPopup(True)layout.addWidget(self.fixed_datetime)# 延时时间选择self.delay_datetime = QDateTimeEdit()self.delay_datetime.setDisplayFormat("HH:mm:ss")self.delay_datetime.setTime(QTime(0, 0, 0))self.delay_datetime.setVisible(False)layout.addWidget(self.delay_datetime)# 连接信号self.fixed_time_radio.toggled.connect(self.on_time_type_changed)# 操作类型action_group = QGroupBox("操作类型")action_layout = QHBoxLayout()action_layout.setContentsMargins(10, 15, 10, 10)self.shutdown_radio = QRadioButton("关机")self.restart_radio = QRadioButton("重启")self.logoff_radio = QRadioButton("注销")self.shutdown_radio.setChecked(True)action_layout.addWidget(self.shutdown_radio)action_layout.addWidget(self.restart_radio)action_layout.addWidget(self.logoff_radio)action_group.setLayout(action_layout)layout.addWidget(action_group)# 选项options_group = QGroupBox("选项")options_layout = QVBoxLayout()options_layout.setContentsMargins(10, 15, 10, 10)self.auto_start_check = QCheckBox("随系统启动")self.loop_exec_check = QCheckBox("循环执行")options_layout.addWidget(self.auto_start_check)options_layout.addWidget(self.loop_exec_check)options_group.setLayout(options_layout)layout.addWidget(options_group)# 剩余时间显示self.remaining_time_label = QLabel()self.remaining_time_label.setAlignment(Qt.AlignCenter)self.remaining_time_label.setObjectName("remaining_time_label")layout.addWidget(self.remaining_time_label)# 按钮布局button_layout = QHBoxLayout()button_layout.setContentsMargins(0, 10, 0, 0)button_layout.setSpacing(15)self.save_btn = QPushButton("保存设置")self.cancel_btn = QPushButton("取消")self.cancel_btn.setObjectName("cancel_btn")self.cancel_btn.setEnabled(False)self.save_btn.clicked.connect(self.save_config)self.cancel_btn.clicked.connect(self.cancel_task)button_layout.addWidget(self.save_btn)button_layout.addWidget(self.cancel_btn)layout.addLayout(button_layout)# 添加弹簧使布局更紧凑layout.addSpacerItem(QSpacerItem(20, 10, QSizePolicy.Minimum, QSizePolicy.Expanding))def on_time_type_changed(self, checked):self.fixed_datetime.setVisible(checked)self.delay_datetime.setVisible(not checked)def update_current_time(self):current_time = datetime.now().strftime("%Y年%m月%d日 %H:%M:%S")self.current_time_label.setText(f"当前时间: {current_time}")def save_config(self):config = configparser.ConfigParser()config['task'] = {'time_type': 'fixed' if self.fixed_time_radio.isChecked() else 'delay','time': self.fixed_datetime.dateTime().toString("HHmmss") if self.fixed_time_radio.isChecked() else self.delay_datetime.time().toString("HHmmss"),'execute_type': 'shutdown' if self.shutdown_radio.isChecked() else 'restart' if self.restart_radio.isChecked() else 'logoff','auto_start': '1' if self.auto_start_check.isChecked() else '0','task_circ': '1' if self.loop_exec_check.isChecked() else '0'}with open(self.config_file, 'w') as f:config.write(f)self.set_auto_start(self.auto_start_check.isChecked())self.cancel_btn.setEnabled(True)  # 保存后启用取消按钮self.start_task()def load_config(self):if not os.path.exists(self.config_file):returnconfig = configparser.ConfigParser()config.read(self.config_file)if 'task' in config:task_config = config['task']# 时间类型if task_config.get('time_type', 'fixed') == 'fixed':self.fixed_time_radio.setChecked(True)time_str = task_config.get('time', '000000')qtime = QTime.fromString(time_str, "HHmmss")current_date = QDateTime.currentDateTime()self.fixed_datetime.setDateTime(QDateTime(current_date.date(), qtime))else:self.delay_time_radio.setChecked(True)time_str = task_config.get('time', '000000')qtime = QTime.fromString(time_str, "HHmmss")self.delay_datetime.setTime(qtime)# 操作类型execute_type = task_config.get('execute_type', 'shutdown')if execute_type == 'shutdown':self.shutdown_radio.setChecked(True)elif execute_type == 'restart':self.restart_radio.setChecked(True)else:self.logoff_radio.setChecked(True)# 选项self.auto_start_check.setChecked(task_config.get('auto_start', '0') == '1')self.loop_exec_check.setChecked(task_config.get('task_circ', '0') == '1')if self.loop_exec_check.isChecked():self.cancel_btn.setEnabled(True)self.start_task()def set_auto_start(self, enable):key = win32con.HKEY_CURRENT_USERsub_key = r"Software\Microsoft\Windows\CurrentVersion\Run"try:reg_key = win32api.RegOpenKey(key, sub_key, 0, win32con.KEY_ALL_ACCESS)if enable:win32api.RegSetValueEx(reg_key, "定时关机", 0, win32con.REG_SZ, sys.executable)else:try:win32api.RegDeleteValue(reg_key, "定时关机")except:passwin32api.RegCloseKey(reg_key)except Exception as e:QMessageBox.warning(self, "警告", f"设置自启动失败: {str(e)}")def start_task(self):if self.task_running:returnself.task_running = Trueself.toggle_components(True)if self.fixed_time_radio.isChecked():target_time = self.fixed_datetime.dateTime().toPyDateTime()now = datetime.now()if target_time < now:target_time += timedelta(days=1)self.target_time = target_timeelse:delay = self.delay_datetime.time()self.target_time = datetime.now() + timedelta(hours=delay.hour(),minutes=delay.minute(),seconds=delay.second())self.countdown_timer.start(1000)self.update_remaining_time()def update_remaining_time(self):now = datetime.now()remaining = self.target_time - nowif remaining.total_seconds() <= 0:self.execute_action()if self.loop_exec_check.isChecked():self.start_task()else:self.cancel_task()returnhours, remainder = divmod(int(remaining.total_seconds()), 3600)minutes, seconds = divmod(remainder, 60)remaining_str = f"{hours}小时{minutes}{seconds}秒"self.remaining_time_label.setText(f"剩余时间: {remaining_str}")# 更新托盘提示self.tray_icon.setToolTip(f"定时关机\n剩余时间: {remaining_str}")def execute_action(self):if self.shutdown_radio.isChecked():os.system("shutdown -s -t 0")elif self.restart_radio.isChecked():os.system("shutdown -r -t 0")else:os.system("shutdown -l")def cancel_task(self):"""取消定时任务"""if not self.task_running:QMessageBox.warning(self, "警告", "没有正在运行的任务")returnreply = QMessageBox.question(self, "确认", "确定要取消定时任务吗?", QMessageBox.Yes | QMessageBox.No)if reply == QMessageBox.Yes:self.task_running = Falseself.countdown_timer.stop()self.remaining_time_label.setText("")self.tray_icon.setToolTip("定时关机")self.toggle_components(False)self.cancel_btn.setEnabled(False)# 显示取消成功的提示QMessageBox.information(self, "提示", "定时任务已取消", QMessageBox.Ok)def toggle_components(self, disabled):self.fixed_time_radio.setDisabled(disabled)self.delay_time_radio.setDisabled(disabled)self.fixed_datetime.setDisabled(disabled)self.delay_datetime.setDisabled(disabled)self.shutdown_radio.setDisabled(disabled)self.restart_radio.setDisabled(disabled)self.logoff_radio.setDisabled(disabled)self.auto_start_check.setDisabled(disabled)self.loop_exec_check.setDisabled(disabled)self.save_btn.setDisabled(disabled)def tray_icon_activated(self, reason):if reason == QSystemTrayIcon.DoubleClick:self.show_normal()def show_normal(self):self.show()self.setWindowState(self.windowState() & ~Qt.WindowMinimized)self.activateWindow()self.raise_()def closeEvent(self, event):"""重写关闭事件,改为最小化到托盘"""if self.isVisible():self.hide()self.tray_icon.show()  # 确保托盘图标显示if not self.first_show:  # 第一次启动时不显示消息self.tray_icon.showMessage("定时关机", "程序已最小化到托盘", QSystemTrayIcon.Information, 2000)self.first_show = Falseevent.ignore()else:# 真正退出程序self.tray_icon.hide()event.accept()def confirm_exit(self):reply = QMessageBox.question(self, '确认', '是否退出?', QMessageBox.Yes | QMessageBox.No, QMessageBox.No)if reply == QMessageBox.Yes:self.tray_icon.hide()QApplication.quit()def main():# 防止重复运行shared = QSharedMemory("定时关机")if not shared.create(512, QSharedMemory.ReadWrite):QMessageBox.warning(None, "警告", "程序已经在运行!")sys.exit(0)# 设置高DPI支持QApplication.setAttribute(Qt.AA_EnableHighDpiScaling)app = QApplication(sys.argv)window = ShutdownApp()# 如果配置了随系统启动且循环执行,则不显示窗口config_file = os.path.join(os.getenv('APPDATA'), 'shutdown_config.ini')if os.path.exists(config_file):config = configparser.ConfigParser()config.read(config_file)if 'task' in config and config['task'].get('auto_start', '0') == '1':if config['task'].get('task_circ', '0') == '1':window.showMinimized()else:window.show()else:window.show()else:window.show()sys.exit(app.exec_())if __name__ == '__main__':main()

🎉 总结与优化方向

🔹 优点

界面简洁,操作方便

系统托盘支持,后台静默运行

支持定时 & 倒计时模式,满足不同需求

🔹 可优化方向

🚀 支持多任务管理(同时设置多个定时任务)

🚀 增加日志记录(记录每次关机任务)

🚀 增加任务进度条(倒计时可视化显示)

如果你对这个工具感兴趣,可以尝试优化它,让它变得更加智能!💡

你会如何改进这个工具?欢迎在评论区交流你的想法! 🚀

📥 资源下载

  • 源码以及exe文件直接下载 ZIP:🔗 点此下载

🚀 赶快下载体验吧,如果觉得有帮助,欢迎 Star 支持!

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

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

相关文章

【MySQL】002.MySQL数据库基础

文章目录 数据库基础1.1 什么是数据库1.2 基本使用创建数据库创建数据表表中插入数据查询表中的数据 1.3 主流数据库1.4 服务器&#xff0c;数据库&#xff0c;表关系1.5 MySQL架构1.6 SQL分类1.7 存储引擎1.7.1 存储引擎1.7.2 查看存储引擎1.7.3 存储引擎对比 前言&#xff1a…

滑动窗口(3)—无重复字符的最长子串

文章目录 题目解析方法一&#xff1a;滑动窗口解法二&#xff08;暴⼒求解&#xff09;&#xff08;不会超时&#xff0c;可以通过&#xff09;&#xff1a;附Java代码 力扣题目&#xff1a;无重复字符的最长子串 题目解析 方法一&#xff1a;滑动窗口 思路和算法 我们先用一…

C++字符串操作详解

引言 字符串处理是编程中最常见的任务之一&#xff0c;而在C中&#xff0c;我们有多种处理字符串的方式。本文将详细介绍C中的字符串操作&#xff0c;包括C风格字符串和C的string类。无论你是C新手还是想巩固基础的老手&#xff0c;这篇文章都能帮你梳理字符串处理的关键知识点…

Vulhub-DC-4靶场通关攻略

下载地址&#xff1a;https://www.vulnhub.com/entry/dc-4,313/ 扫描IP地址 arp-sacn -l扫描端口&#xff0c;开启了80和22端口 nmap -p- 192.168.112.140访问80端口 扫描目录&#xff0c;并没有发现敏感目录 尝试爆破 爆破成功&#xff0c;用户名admin 密码happy 登录成功 …

OfficePlus去掉PDF文件右键菜单里的PDF转换

今天在吾爱破解论坛看到一个求助帖&#xff0c;说是OfficePlus&#xff0c;安装后&#xff0c;PDF文件的右键菜单里多了PDF转换&#xff0c;想去掉&#xff0c;不知道怎么弄。底下的回复基本都是百度复制或者AI搜索出的答案&#xff0c;大致就是找注册表里CLASSID下的菜单栏相关…

大模型本地部署系列(3) Ollama部署QwQ[阿里云通义千问]

大家好&#xff0c;我是AI研究者&#xff0c; 今天教大家部署 一个阿里云通义千问大模型。 QwQ大模型简介 QwQ是由阿里云通义千问&#xff08;Qwen&#xff09;团队推出的开源推理大模型&#xff0c;专注于提升AI在数学、编程和复杂逻辑推理方面的能力。其核心特点包括&#x…

微信小程序学习实录12:掌握大数据量轨迹展示的MySQL结构设计

获取经纬度信息后&#xff0c;mysql建立数据表po_trajectory&#xff0c;字段包含tra_id、longitude、latitude、tra_time和openid。 为微信小程序创建的 po_trajectory 数据表&#xff0c;字段包含 tra_id、longitude、latitude、tra_time 和 openid&#xff0c;从结构设计上…

计算机系统---性能指标(3)续航与散热

计算机电池续航的性能指标 一、电池基础物理指标 电池容量&#xff08;核心指标&#xff09; 单位&#xff1a; 毫安时&#xff08;mAh&#xff09;&#xff1a;常见于手机/平板&#xff0c;反映电池存储电荷量&#xff0c;需结合电压计算实际能量&#xff08;如3.7V电池&…

贪心算法之最小生成树问题

1. 贪心算法的基本思想 贪心算法在每一步都选择局部最优的边&#xff0c;希望最终得到整体最优的生成树。常见的两种 MST 算法为 Kruskal 算法 和 Prim 算法。这两者均满足贪心选择性质和最优子结构性质&#xff0c;即&#xff1a; 贪心选择性质&#xff1a;局部最优选择&…

LeetCode hot 100—编辑距离

题目 给你两个单词 word1 和 word2&#xff0c; 请返回将 word1 转换成 word2 所使用的最少操作数 。 你可以对一个单词进行如下三种操作&#xff1a; 插入一个字符删除一个字符替换一个字符 示例 示例 1&#xff1a; 输入&#xff1a;word1 "horse", word2 &q…

2.3 Spark运行架构与流程

Spark运行架构与流程包括几个核心概念&#xff1a;Driver负责提交应用并初始化作业&#xff0c;Executor在工作节点上执行任务&#xff0c;作业是一系列计算任务&#xff0c;任务是作业的基本执行单元&#xff0c;阶段是一组并行任务。Spark支持多种运行模式&#xff0c;包括单…

NO.82十六届蓝桥杯备战|动态规划-从记忆化搜索到动态规划|下楼梯|数字三角形(C++)

记忆化搜索 在搜索的过程中&#xff0c;如果搜索树中有很多重复的结点&#xff0c;此时可以通过⼀个"备忘录"&#xff0c;记录第⼀次搜索到的结果。当下⼀次搜索到这个结点时&#xff0c;直接在"备忘录"⾥⾯找结果。其中&#xff0c;搜索树中的⼀个⼀个结点…

使用 VBA 宏创建一个选择全部word图片快捷指令,进行图片格式编辑

使用 VBA 宏批量选择图片 ✅ 第一步&#xff1a;创建 .dotm 加载项文件 1、使用环境 office word 365&#xff0c;文件格式为.docx 图片格式为.PNG 2、创建 .dotm 加载项文件 打开 Word&#xff0c;新建一个空白文档。 按下 Alt F11 打开 VBA 编辑器。 点击菜单栏&#xff…

深度学习的下一个突破:从图像识别到情境理解

引言 过去十年&#xff0c;深度学习在图像识别领域取得了惊人的突破。从2012年ImageNet大赛上的AlexNet&#xff0c;到后来的ResNet、EfficientNet&#xff0c;再到近年来Transformer架构的崛起&#xff0c;AI已经能在许多任务上超越人类&#xff0c;比如人脸识别、目标检测、医…

使用dyn4j做碰撞检测

文章目录 前言一、环境准备添加依赖基本概念 二、实现步骤1.创建世界2.添加物体3.设置碰撞监听器4.更新世界 三、完整代码示例四、优化补充总结 前言 dyn4j 提供了高效的碰撞检测和物理模拟功能&#xff0c;适用于游戏开发、动画制作以及其他需要物理交互的场景。通过简单的 A…

VS Code settings.json 文件中常用的预定义变量‌及其用途说明

VS Code settings.json 常用预定义变量 以下是 Visual Studio Code 配置文件中常用的预定义变量列表&#xff1a; 1. 工作区相关变量 变量描述示例值${workspaceFolder}当前工作区根目录的绝对路径C:/projects/my-project${workspaceFolderBasename}工作区文件夹名称&#x…

elasticSearch-搜索引擎

搜索引擎的优势 有了数据库分页查询&#xff0c;为什么还需要搜索引擎&#xff1f; 搜索引擎速度上很快数据库分页查询&#xff0c;随着数据库数据量增大&#xff0c;页数靠后&#xff0c;会导致搜索速度变慢&#xff0c;但是搜索引擎不会搜索引擎支持分词查询&#xff0c;地…

安装OpenJDK1.8 17 (macos M芯片)

安装OpenJDK 1.8 下载完后&#xff0c;解压&#xff0c;打开 环境变量的配置文件即可 vim ~/.zshrc #export JAVA_HOME/Users/xxxxx/jdk-21.jdk/Contents/Home #export JAVA_HOME/Users/xxxxx/jdk-17.jdk/Contents/Home #export JAVA_HOME/Users/xxxxx/jdk-11.jdk/Contents…

断言与反射——以golang为例

断言 x.(T) 检查x的动态类型是否是T&#xff0c;其中x必须是接口值。 简单使用 func main() {var x interface{}x 100value1, ok : x.(int)if ok {fmt.Println(value1)}value2, ok : x.(string)if ok {//未打印fmt.Println(value2)} }需要注意如果不接受第二个参数就是OK,这…

Java设计模式:系统性解析与核心模式

一、设计模式三大分类总览 创建型模式&#xff08;5种&#xff09; 核心目标&#xff1a;对象创建的优化与解耦 单例模式&#xff08;Singleton&#xff09; 工厂模式&#xff08;Factory&#xff09; 抽象工厂模式&#xff08;Abstract Factory&#xff09; 建造者模式&#…