微语
个人中心
写文章
登录
注册
搜索
登录
搜索
guolin
这个站长还在上小学,平时没多少时间上网,并不是懒,是妈妈不让……
累计撰写
22
篇文章
累计收到
12
条评论
微语
个人中心
写文章
登录
注册
推荐
OpenClaw:从 “聊天 AI” 到 “本地执行中枢”,2026 年最值得关注的开源智能体革命
推荐
AI工具合集|普通人也能高效利用的科技神器,告别无效忙碌
最新文章
2026-3-15
置顶
OpenClaw:从 “聊天 AI” 到 “本地执行中枢”,2026 年最值得关注的开源智能体革命
2026 年开年,AI 圈最火的开源项目非OpenClaw莫属。上线仅两个多月,GitHub 星标突破 30 万,3 月单月连发 6 个版本,从个人轻量工具快速进化为支持 K8s 集群、多智能体调度、记忆热插拔的企业级平台。它不再是只会对话的 “嘴炮 AI”,而是能直接操作文件、运行代码、跨应用自动化的本地执行中枢,正在重新定义人与计算机的交互方式。 一、O...
2026年-3月-15日
953 阅读
0 评论
科技好文
2026-2-26
置顶
欢迎来到郭的秀
欢迎来到郭的秀,在这里,你可以发表自己的文章,也可以评论,但不要垃圾评论,也不要恶意灌水,保持他人的友好相处,期待你在这里有所收获,有所成长,那么准备好了吗,接下来就让我们退出这篇文章,一起开始这个博客之旅吧!
2026年-2月-26日
918 阅读
2 评论
交友聊天
2026-7-5
关机助手
通过网盘分享的文件:shutdown.exe 链接: https://pan.baidu.com/s/1QQTv9mcMobODVt4f8vQ9og 提取码: 2dxe 复制这段内容后打开百度网盘手机App,操作更方便哦 打开看看,测试下
2026年-7月-5日
144 阅读
0 评论
2026-6-21
代码智能新纪元:从 Codex 到 Code LLM,AI 编程革命的技术、产业与未来
引言:当 AI 成为程序员的 “第二大脑” 2021 年,OpenAI 发布Codex模型,以自然语言生成可运行代码的能力震撼全球,标志着人工智能正式从 “理解代码” 迈向 “创造代码”。短短数年,以 Codex 为起点,GitHub Copilot、CodeLlama、StarCoder、DeepSeek-Coder 等代码大模型(Code LLM)如雨...
2026年-6月-21日
164 阅读
0 评论
科技好文
2026-6-19
shuidown
""" Windows智能关机助手 - 重构版 保持原界面布局,改进代码质量、错误处理和稳定性 功能:关机/重启/睡眠选择、倒计时/定时执行、无人操作自动关机/睡眠、系统托盘后台运行 作者:郭麟 版本:2.0 """ import sys import os import time import json import logging import threading import ctypes import ctypes.wintypes import platform from datetime import datetime, timedelta from typing import Optional from enum import Enum from PyQt5.QtWidgets import from PyQt5.QtCore import from PyQt5.QtGui import * ========== 日志配置 ========== def setup_logging(): """配置日志系统""" log_dir = os.path.join(os.path.expanduser("~"), "AppData", "Local", "ShutdownHelper") os.makedirs(log_dir, exist_ok=True) log_file = os.path.join(log_dir, "shutdown_helper.log") logging.basicConfig( level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', handlers=[ logging.FileHandler(log_file, encoding='utf-8'), logging.StreamHandler() ] ) return logging.getLogger(__name__) logger = setup_logging() ========== 配置管理 ========== class Config: """配置管理""" CONFIG_FILE = os.path.join(os.path.expanduser("~"), "AppData", "Local", "ShutdownHelper", "config.json") DEFAULTS = { "idle_threshold": 300, "idle_action": "sleep", # "shutdown" 或 "sleep" "default_hours": 0, "default_minutes": 30, "default_seconds": 0 } @classmethod def load(cls): try: if os.path.exists(cls.CONFIG_FILE): with open(cls.CONFIG_FILE, 'r', encoding='utf-8') as f: config = json.load(f) for key, value in cls.DEFAULTS.items(): if key not in config: config = value return config except Exception as e: logger.error(f"加载配置失败: {e}") return cls.DEFAULTS.copy() @classmethod def save(cls, config): try: os.makedirs(os.path.dirname(cls.CONFIG_FILE), exist_ok=True) with open(cls.CONFIG_FILE, 'w', encoding='utf-8') as f: json.dump(config, f, indent=2, ensure_ascii=False) return True except Exception as e: logger.error(f"保存配置失败: {e}") return False ========== Windows API ========== class WinAPI: """Windows API 封装""" @staticmethod def is_admin(): try: return ctypes.windll.shell32.IsUserAnAdmin() except: return False @staticmethod def request_admin(): if not WinAPI.is_admin(): args = ' '.join(f'"{arg}"' if ' ' in arg else arg for arg in sys.argv) ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, args, None, 1) sys.exit() @staticmethod def get_idle_seconds(): try: class LASTINPUTINFO(ctypes.Structure): _fields_ = lii = LASTINPUTINFO() lii.cbSize = ctypes.sizeof(LASTINPUTINFO) if ctypes.windll.user32.GetLastInputInfo(ctypes.byref(lii)): tick = ctypes.windll.kernel32.GetTickCount() return (tick - lii.dwTime) // 1000 except Exception as e: logger.error(f"获取空闲时间失败: {e}") return 0 @staticmethod def shutdown(): try: ctypes.windll.advapi32.SetProcessShutdownParameters(0x100, 0) return ctypes.windll.user32.ExitWindowsEx(0x00000001, 0) != 0 except Exception as e: logger.error(f"关机失败: {e}") return False @staticmethod def restart(): try: ctypes.windll.advapi32.SetProcessShutdownParameters(0x100, 0) return ctypes.windll.user32.ExitWindowsEx(0x00000002, 0) != 0 except Exception as e: logger.error(f"重启失败: {e}") return False @staticmethod def sleep(): try: return ctypes.windll.powrprof.SetSuspendState(0, 1, 0) != 0 except Exception as e: logger.error(f"睡眠失败: {e}") return False @staticmethod def cancel_shutdown(): try: os.system("shutdown /a 2>nul") return True except: return False ========== 空闲监控线程 ========== class IdleMonitor(QThread): """监控系统空闲时间""" idle_timeout = pyqtSignal() def __init__(self, threshold_seconds): super().__init__() self.threshold = threshold_seconds self.is_running = True self._consecutive_idle = 0 def run(self): while self.is_running: idle_sec = WinAPI.get_idle_seconds() if idle_sec >= self.threshold: self._consecutive_idle += 1 if self._consecutive_idle >= 3: self.idle_timeout.emit() self._consecutive_idle = 0 self.sleep(30) continue else: self._consecutive_idle = 0 # 动态调整轮询间隔 if idle_sec > self.threshold * 0.7: self.sleep(10) else: self.sleep(5) def stop(self): self.is_running = False self.quit() self.wait() ========== 倒计时线程 ========== class ShutdownTimer(QThread): """倒计时线程""" countdown_signal = pyqtSignal(str, int, str) # 时间文本, 进度, 描述 shutdown_signal = pyqtSignal(str) # 操作类型 def __init__(self, seconds, operation): super().__init__() self.seconds = seconds self.total_seconds = seconds self.operation = operation self.is_running = True self.is_paused = False self.pause_cond = threading.Condition() def run(self): while self.is_running and self.seconds > 0: if not self.is_paused: remaining = self.seconds hours = remaining // 3600 minutes = (remaining % 3600) // 60 seconds = remaining % 60 countdown_text = f"{hours:02d}:{minutes:02d}:{seconds:02d}" progress = int((self.total_seconds - self.seconds) / self.total_seconds * 100) if hours > 0: time_desc = f"{hours}小时{minutes}分" elif minutes > 0: time_desc = f"{minutes}分钟{seconds}秒" else: time_desc = f"{seconds}秒" self.countdown_signal.emit(countdown_text, progress, time_desc) self.seconds -= 1 time.sleep(1) else: with self.pause_cond: self.pause_cond.wait() if self.is_running and self.seconds <= 0: self.shutdown_signal.emit(self.operation) def pause(self): self.is_paused = True def resume(self): self.is_paused = False with self.pause_cond: self.pause_cond.notify() def stop(self): self.is_running = False self.is_paused = False with self.pause_cond: self.pause_cond.notify() self.quit() self.wait() ========== 主窗口 ========== class WindowsShutdownApp(QMainWindow): def init(self): super().init() # 加载配置 self.config = Config.load() # 状态变量 self.shutdown_timer = None self.current_operation = "关机" self.is_minimized_mode = False self.original_geometry = None # 空闲监控 self.idle_monitor = None self.auto_idle_enabled = False self.idle_threshold = self.config.get("idle_threshold", 300) self.idle_action = self.config.get("idle_action", "sleep") # "shutdown" 或 "sleep" # 系统托盘 self.tray_icon = None # 初始化UI self.init_ui() self.setup_tray_icon() # 加载配置到控件 self.load_config() # 日志 self.logger = logger def init_ui(self): """初始化UI - 保持原界面布局""" self.setWindowTitle("智能关机助手") self.setFixedSize(500, 820) # 稍微加高以容纳新控件 central_widget = QWidget() self.setCentralWidget(central_widget) main_layout = QVBoxLayout(central_widget) main_layout.setSpacing(8) main_layout.setContentsMargins(25, 15, 25, 15) central_widget.setStyleSheet("background-color: #f5f5f5;") # ========== 标题 ========== title_label = QLabel("🖥️ 智能关机助手") title_label.setStyleSheet("font-size: 22px; font-weight: bold; color: #333; padding: 5px 0;") title_label.setAlignment(Qt.AlignCenter) main_layout.addWidget(title_label) # ========== 倒计时显示 ========== self.countdown_label = QLabel("00:00:00") self.countdown_label.setStyleSheet(""" font-size: 56px; font-weight: bold; color: #2196F3; font-family: 'Consolas', monospace; padding: 20px; background-color: white; border-radius: 15px; border: 2px solid #e0e0e0; """) self.countdown_label.setAlignment(Qt.AlignCenter) main_layout.addWidget(self.countdown_label) # ========== 进度条 ========== self.progress_bar = QProgressBar() self.progress_bar.setRange(0, 100) self.progress_bar.setValue(0) self.progress_bar.setTextVisible(False) self.progress_bar.setFixedHeight(8) self.progress_bar.setStyleSheet(""" QProgressBar { border: none; background-color: #e0e0e0; border-radius: 4px; } QProgressBar::chunk { background-color: #2196F3; border-radius: 4px; } """) main_layout.addWidget(self.progress_bar) # ========== 操作选择分组框 ========== op_group = QGroupBox("选择操作") op_group.setStyleSheet(""" QGroupBox { font-size: 13px; font-weight: bold; color: #555; border: 1px solid #ddd; border-radius: 8px; margin-top: 5px; padding-top: 12px; background-color: white; } QGroupBox::title { subcontrol-origin: margin; left: 15px; padding: 0 8px; } """) op_layout = QHBoxLayout() op_layout.setSpacing(15) op_layout.setContentsMargins(15, 10, 15, 10) self.btn_shutdown = self._create_op_button("🔌 关机", "#f44336") self.btn_restart = self._create_op_button("🔄 重启", "#ff9800") self.btn_sleep = self._create_op_button("😴 睡眠", "#4caf50") self.btn_shutdown.setChecked(True) self.btn_shutdown.clicked.connect(lambda: self.on_operation_changed("关机")) self.btn_restart.clicked.connect(lambda: self.on_operation_changed("重启")) self.btn_sleep.clicked.connect(lambda: self.on_operation_changed("睡眠")) op_layout.addWidget(self.btn_shutdown) op_layout.addWidget(self.btn_restart) op_layout.addWidget(self.btn_sleep) op_group.setLayout(op_layout) main_layout.addWidget(op_group) # ========== 时间设置分组框 ========== time_group = QGroupBox("时间设置") time_group.setStyleSheet(""" QGroupBox { font-size: 13px; font-weight: bold; color: #555; border: 1px solid #ddd; border-radius: 8px; margin-top: 5px; padding-top: 12px; background-color: white; } QGroupBox::title { subcontrol-origin: margin; left: 15px; padding: 0 8px; } """) time_layout = QVBoxLayout() time_layout.setSpacing(10) time_layout.setContentsMargins(15, 10, 15, 10) # 执行模式选择 mode_layout = QHBoxLayout() mode_layout.addWidget(QLabel("执行模式:")) self.mode_combo = QComboBox() self.mode_combo.addItems() self.mode_combo.setStyleSheet("padding: 5px; border: 1px solid #ddd; border-radius: 5px; min-width: 100px;") self.mode_combo.currentTextChanged.connect(self.on_mode_changed) mode_layout.addWidget(self.mode_combo) mode_layout.addStretch() time_layout.addLayout(mode_layout) # 倒计时设置 self.timer_widget = QWidget() timer_layout = QHBoxLayout(self.timer_widget) timer_layout.setContentsMargins(0, 0, 0, 0) timer_layout.setSpacing(10) timer_layout.addWidget(QLabel("时长:")) self.hour_spin = QSpinBox() self.hour_spin.setRange(0, 23) self.hour_spin.setValue(self.config.get("default_hours", 0)) self.hour_spin.setSuffix(" 时") self.hour_spin.setFixedWidth(70) timer_layout.addWidget(self.hour_spin) self.minute_spin = QSpinBox() self.minute_spin.setRange(0, 59) self.minute_spin.setValue(self.config.get("default_minutes", 30)) self.minute_spin.setSuffix(" 分") self.minute_spin.setFixedWidth(70) timer_layout.addWidget(self.minute_spin) self.second_spin = QSpinBox() self.second_spin.setRange(0, 59) self.second_spin.setValue(self.config.get("default_seconds", 0)) self.second_spin.setSuffix(" 秒") self.second_spin.setFixedWidth(70) timer_layout.addWidget(self.second_spin) timer_layout.addStretch() time_layout.addWidget(self.timer_widget) # 定时设置 self.schedule_widget = QWidget() schedule_layout = QHBoxLayout(self.schedule_widget) schedule_layout.setContentsMargins(0, 0, 0, 0) schedule_layout.setSpacing(10) schedule_layout.addWidget(QLabel("时间:")) self.date_edit = QDateEdit() self.date_edit.setDate(QDate.currentDate()) self.date_edit.setDisplayFormat("yyyy-MM-dd") self.date_edit.setCalendarPopup(True) self.date_edit.setFixedWidth(120) schedule_layout.addWidget(self.date_edit) self.time_edit = QTimeEdit() self.time_edit.setTime(QTime.currentTime().addSecs(1800)) self.time_edit.setDisplayFormat("HH:mm:ss") self.time_edit.setFixedWidth(90) schedule_layout.addWidget(self.time_edit) schedule_layout.addStretch() time_layout.addWidget(self.schedule_widget) self.schedule_widget.hide() time_group.setLayout(time_layout) main_layout.addWidget(time_group) # ========== 无人操作自动关机/睡眠分组框 ========== idle_group = QGroupBox("无人操作自动处理") idle_group.setStyleSheet(""" QGroupBox { font-size: 13px; font-weight: bold; color: #555; border: 1px solid #ddd; border-radius: 8px; margin-top: 5px; padding-top: 12px; background-color: white; } QGroupBox::title { subcontrol-origin: margin; left: 15px; padding: 0 8px; } """) idle_layout = QVBoxLayout() idle_layout.setSpacing(8) idle_layout.setContentsMargins(15, 10, 15, 10) # 第一行:启用开关 + 时间设置 row1_layout = QHBoxLayout() row1_layout.setSpacing(10) self.idle_checkbox = QCheckBox("当用户无操作超过") self.idle_checkbox.setStyleSheet("font-size: 12px;") self.idle_checkbox.stateChanged.connect(self.on_idle_checkbox_changed) row1_layout.addWidget(self.idle_checkbox) self.idle_min_spin = QSpinBox() self.idle_min_spin.setRange(1, 60) self.idle_min_spin.setValue(self.idle_threshold // 60) self.idle_min_spin.setSuffix(" 分钟") self.idle_min_spin.setFixedWidth(80) self.idle_min_spin.setEnabled(False) self.idle_min_spin.valueChanged.connect(self.on_idle_threshold_changed) row1_layout.addWidget(self.idle_min_spin) row1_layout.addStretch() idle_layout.addLayout(row1_layout) # 第二行:操作选择(关机/睡眠) row2_layout = QHBoxLayout() row2_layout.setSpacing(10) row2_layout.addWidget(QLabel("执行操作:")) self.idle_action_shutdown = QRadioButton("关机") self.idle_action_sleep = QRadioButton("睡眠") # 设置默认选中 if self.idle_action == "shutdown": self.idle_action_shutdown.setChecked(True) else: self.idle_action_sleep.setChecked(True) # 默认禁用 self.idle_action_shutdown.setEnabled(False) self.idle_action_sleep.setEnabled(False) self.idle_action_shutdown.toggled.connect(self.on_idle_action_changed) self.idle_action_sleep.toggled.connect(self.on_idle_action_changed) row2_layout.addWidget(self.idle_action_shutdown) row2_layout.addWidget(self.idle_action_sleep) row2_layout.addStretch() idle_layout.addLayout(row2_layout) idle_group.setLayout(idle_layout) main_layout.addWidget(idle_group) # ========== 控制按钮 ========== btn_layout = QHBoxLayout() btn_layout.setSpacing(15) self.start_btn = QPushButton("开始") self.start_btn.setFixedHeight(45) self.start_btn.setStyleSheet(""" QPushButton { background-color: #2196F3; color: white; font-size: 15px; font-weight: bold; border: none; border-radius: 8px; } QPushButton:hover { background-color: #1976D2; } QPushButton:disabled { background-color: #bdbdbd; } """) self.start_btn.clicked.connect(self.start_operation) btn_layout.addWidget(self.start_btn) self.pause_btn = QPushButton("暂停") self.pause_btn.setFixedHeight(45) self.pause_btn.setStyleSheet(""" QPushButton { background-color: #ff9800; color: white; font-size: 15px; font-weight: bold; border: none; border-radius: 8px; } QPushButton:hover { background-color: #f57c00; } QPushButton:disabled { background-color: #bdbdbd; } """) self.pause_btn.clicked.connect(self.pause_operation) self.pause_btn.setEnabled(False) btn_layout.addWidget(self.pause_btn) self.cancel_btn = QPushButton("取消") self.cancel_btn.setFixedHeight(45) self.cancel_btn.setStyleSheet(""" QPushButton { background-color: #f44336; color: white; font-size: 15px; font-weight: bold; border: none; border-radius: 8px; } QPushButton:hover { background-color: #d32f2f; } QPushButton:disabled { background-color: #bdbdbd; } """) self.cancel_btn.clicked.connect(self.cancel_operation) self.cancel_btn.setEnabled(False) btn_layout.addWidget(self.cancel_btn) main_layout.addLayout(btn_layout) # ========== 小窗控制按钮 ========== self.mini_control_widget = QWidget() mini_layout = QHBoxLayout(self.mini_control_widget) mini_layout.setSpacing(10) mini_layout.setContentsMargins(0, 0, 0, 0) self.mini_pause_btn = QPushButton("⏸") self.mini_pause_btn.setFixedSize(40, 40) self.mini_pause_btn.setStyleSheet(self._get_mini_btn_style("#ff9800")) self.mini_pause_btn.clicked.connect(self.pause_operation) self.mini_pause_btn.setEnabled(False) mini_layout.addWidget(self.mini_pause_btn) self.mini_cancel_btn = QPushButton("✕") self.mini_cancel_btn.setFixedSize(40, 40) self.mini_cancel_btn.setStyleSheet(self._get_mini_btn_style("#f44336")) self.mini_cancel_btn.clicked.connect(self.cancel_operation) self.mini_cancel_btn.setEnabled(False) mini_layout.addWidget(self.mini_cancel_btn) main_layout.addWidget(self.mini_control_widget) self.mini_control_widget.hide() # ========== 辅助方法 ========== def _create_op_button(self, text, color): btn = QPushButton(text) btn.setCheckable(True) btn.setFixedHeight(50) btn.setStyleSheet(f""" QPushButton {{ background-color: white; color: {color}; font-size: 14px; font-weight: bold; border: 2px solid {color}; border-radius: 8px; }} QPushButton:hover {{ background-color: {color}20; }} QPushButton:checked {{ background-color: {color}; color: white; }} """) return btn def _get_mini_btn_style(self, color): return f""" QPushButton {{ background-color: {color}; color: white; font-size: 18px; font-weight: bold; border: none; border-radius: 20px; }} QPushButton:hover {{ opacity: 0.8; }} QPushButton:disabled {{ background-color: #bdbdbd; }} """ def load_config(self): """加载配置到控件""" self.idle_min_spin.setValue(self.config.get("idle_threshold", 300) // 60) self.hour_spin.setValue(self.config.get("default_hours", 0)) self.minute_spin.setValue(self.config.get("default_minutes", 30)) self.second_spin.setValue(self.config.get("default_seconds", 0)) # 恢复空闲操作选择 if self.config.get("idle_action", "sleep") == "shutdown": self.idle_action_shutdown.setChecked(True) else: self.idle_action_sleep.setChecked(True) def save_config(self): """保存配置""" self.config = self.idle_min_spin.value() * 60 self.config = self.idle_action self.config = self.hour_spin.value() self.config = self.minute_spin.value() self.config = self.second_spin.value() Config.save(self.config) # ========== 操作选择 ========== def on_operation_changed(self, operation_name): self.current_operation = operation_name for btn in : btn.setChecked(False) if operation_name == "关机": self.btn_shutdown.setChecked(True) elif operation_name == "重启": self.btn_restart.setChecked(True) else: self.btn_sleep.setChecked(True) self.setWindowTitle(f"智能关机助手 - 已选择: {operation_name}") # ========== 模式切换 ========== def on_mode_changed(self, mode): if mode == "倒计时": self.timer_widget.show() self.schedule_widget.hide() elif mode == "定时": self.timer_widget.hide() self.schedule_widget.show() else: self.timer_widget.hide() self.schedule_widget.hide() # ========== 计算等待时间 ========== def calculate_wait_seconds(self): mode = self.mode_combo.currentText() if mode == "立即执行": return 0 elif mode == "倒计时": return (self.hour_spin.value() * 3600 + self.minute_spin.value() * 60 + self.second_spin.value()) else: target = datetime.combine( self.date_edit.date().toPyDate(), self.time_edit.time().toPyTime() ) now = datetime.now() if target < now: target += timedelta(days=1) return int((target - now).total_seconds()) # ========== 开始操作 ========== def start_operation(self): try: mode = self.mode_combo.currentText() seconds = self.calculate_wait_seconds() if mode == "立即执行": self.execute_operation(self.current_operation) elif seconds <= 0: QMessageBox.warning(self, "提示", "请设置有效的时间!") return else: self.start_btn.setEnabled(False) self.pause_btn.setEnabled(True) self.cancel_btn.setEnabled(True) self.mini_pause_btn.setEnabled(True) self.mini_cancel_btn.setEnabled(True) self.shutdown_timer = ShutdownTimer(seconds, self.current_operation) self.shutdown_timer.countdown_signal.connect(self.update_countdown) self.shutdown_timer.shutdown_signal.connect(self.execute_operation) self.shutdown_timer.start() self.logger.info(f"开始倒计时: {seconds}秒, 操作: {self.current_operation}") self.minimize_to_corner() except Exception as e: self.logger.error(f"启动失败: {e}") QMessageBox.critical(self, "错误", f"启动失败: {str(e)}") # ========== 小窗模式 ========== def minimize_to_corner(self): if not self.is_minimized_mode: self.is_minimized_mode = True self.original_geometry = self.geometry() for widget in self.findChildren(QGroupBox): widget.hide() self.start_btn.hide() self.pause_btn.hide() self.cancel_btn.hide() self.mini_control_widget.show() self.setFixedSize(350, 200) self.countdown_label.setStyleSheet(""" font-size: 40px; font-weight: bold; color: #2196F3; font-family: 'Consolas', monospace; padding: 10px; background-color: white; border-radius: 10px; border: 1px solid #e0e0e0; """) self.progress_bar.setFixedHeight(6) screen = QApplication.primaryScreen().geometry() self.move(screen.width() - 370, screen.height() - 240) self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint) self.show() def restore_to_normal(self): if self.is_minimized_mode: self.is_minimized_mode = False for widget in self.findChildren(QGroupBox): widget.show() self.start_btn.show() self.pause_btn.show() self.cancel_btn.show() self.mini_control_widget.hide() self.setFixedSize(500, 820) if self.original_geometry: self.setGeometry(self.original_geometry) self.countdown_label.setStyleSheet(""" font-size: 56px; font-weight: bold; color: #2196F3; font-family: 'Consolas', monospace; padding: 20px; background-color: white; border-radius: 15px; border: 2px solid #e0e0e0; """) self.progress_bar.setFixedHeight(8) self.setWindowFlags(Qt.Window) self.show() def mouseDoubleClickEvent(self, event): if self.is_minimized_mode: self.restore_to_normal() elif self.shutdown_timer and self.shutdown_timer.isRunning(): self.minimize_to_corner() event.accept() # ========== 倒计时更新 ========== def update_countdown(self, text, progress, time_desc): self.countdown_label.setText(text) self.progress_bar.setValue(progress) self.setWindowTitle(f"智能关机助手 - 剩余 {time_desc}") # ========== 暂停/继续 ========== def pause_operation(self): if self.shutdown_timer: if self.shutdown_timer.is_paused: self.shutdown_timer.resume() self.pause_btn.setText("暂停") self.mini_pause_btn.setText("⏸") else: self.shutdown_timer.pause() self.pause_btn.setText("继续") self.mini_pause_btn.setText("▶") # ========== 取消操作 ========== def cancel_operation(self): if self.shutdown_timer: self.shutdown_timer.stop() self.shutdown_timer = None self.countdown_label.setText("00:00:00") self.progress_bar.setValue(0) self.start_btn.setEnabled(True) self.pause_btn.setEnabled(False) self.pause_btn.setText("暂停") self.cancel_btn.setEnabled(False) self.mini_pause_btn.setEnabled(False) self.mini_pause_btn.setText("⏸") self.mini_cancel_btn.setEnabled(False) if self.is_minimized_mode: self.restore_to_normal() self.setWindowTitle("智能关机助手") WinAPI.cancel_shutdown() self.logger.info("取消操作") # ========== 执行操作 ========== def execute_operation(self, operation=None): op = operation or self.current_operation self.logger.info(f"执行操作: {op}") success = False try: if op == "关机": success = WinAPI.shutdown() if not success: os.system("shutdown /s /t 5") success = True self.setWindowTitle("智能关机助手 - 正在关机") elif op == "重启": success = WinAPI.restart() if not success: os.system("shutdown /r /t 5") success = True self.setWindowTitle("智能关机助手 - 正在重启") else: # 睡眠 success = WinAPI.sleep() if not success: os.system("rundll32.exe powrprof.dll,SetSuspendState 0,1,0") success = True self.setWindowTitle("智能关机助手 - 正在睡眠") if not success: raise RuntimeError("操作执行失败") except Exception as e: self.logger.error(f"执行操作失败: {e}") QMessageBox.critical(self, "错误", f"操作失败: {str(e)}") self.reset_ui() return QTimer.singleShot(3000, self.reset_ui) def reset_ui(self): self.countdown_label.setText("00:00:00") self.progress_bar.setValue(0) self.start_btn.setEnabled(True) self.pause_btn.setEnabled(False) self.pause_btn.setText("暂停") self.cancel_btn.setEnabled(False) self.mini_pause_btn.setEnabled(False) self.mini_pause_btn.setText("⏸") self.mini_cancel_btn.setEnabled(False) self.setWindowTitle("智能关机助手") if self.is_minimized_mode: self.restore_to_normal() # ========== 无人操作自动关机/睡眠 ========== def on_idle_checkbox_changed(self, state): self.auto_idle_enabled = (state == Qt.Checked) self.idle_min_spin.setEnabled(self.auto_idle_enabled) self.idle_action_shutdown.setEnabled(self.auto_idle_enabled) self.idle_action_sleep.setEnabled(self.auto_idle_enabled) if self.auto_idle_enabled: self.save_config() self.start_idle_monitor() action_name = "关机" if self.idle_action == "shutdown" else "睡眠" self.logger.info(f"启用空闲监控,超时后执行: {action_name}") else: self.stop_idle_monitor() self.logger.info("禁用空闲监控") def on_idle_threshold_changed(self, value): if self.auto_idle_enabled: self.idle_threshold = value * 60 self.save_config() if self.idle_monitor: self.start_idle_monitor() def on_idle_action_changed(self): """空闲操作选择变化""" if self.idle_action_shutdown.isChecked(): self.idle_action = "shutdown" else: self.idle_action = "sleep" self.save_config() if self.auto_idle_enabled: action_name = "关机" if self.idle_action == "shutdown" else "睡眠" self.logger.info(f"空闲操作切换为: {action_name}") def start_idle_monitor(self): self.stop_idle_monitor() self.idle_monitor = IdleMonitor(self.idle_threshold) self.idle_monitor.idle_timeout.connect(self.on_idle_timeout) self.idle_monitor.start() def stop_idle_monitor(self): if self.idle_monitor: self.idle_monitor.stop() self.idle_monitor = None def on_idle_timeout(self): """空闲超时处理""" if self.shutdown_timer and self.shutdown_timer.isRunning(): return # 根据用户选择执行关机或睡眠 if self.idle_action == "shutdown": self.logger.info("空闲超时,执行自动关机") self.execute_operation("关机") else: self.logger.info("空闲超时,执行自动睡眠") self.execute_operation("睡眠") # ========== 系统托盘 ========== def setup_tray_icon(self): self.tray_icon = QSystemTrayIcon(self) icon = self.style().standardIcon(QStyle.SP_ComputerIcon) self.tray_icon.setIcon(icon) self.tray_icon.setToolTip("智能关机助手") tray_menu = QMenu() show_action = QAction("显示窗口", self) show_action.triggered.connect(self.show_window) tray_menu.addAction(show_action) hide_action = QAction("隐藏窗口", self) hide_action.triggered.connect(self.hide_window) tray_menu.addAction(hide_action) tray_menu.addSeparator() exit_action = QAction("退出程序", self) exit_action.triggered.connect(self.exit_app) tray_menu.addAction(exit_action) self.tray_icon.setContextMenu(tray_menu) self.tray_icon.activated.connect(self.on_tray_icon_activated) self.tray_icon.show() def on_tray_icon_activated(self, reason): if reason == QSystemTrayIcon.DoubleClick: self.show_window() def show_window(self): self.showNormal() self.raise_() self.activateWindow() def hide_window(self): self.hide() def exit_app(self): self.logger.info("退出程序") self.stop_idle_monitor() if self.shutdown_timer: self.shutdown_timer.stop() WinAPI.cancel_shutdown() if self.tray_icon: self.tray_icon.hide() QApplication.quit() # ========== 关闭事件 ========== def closeEvent(self, event): event.ignore() self.hide() if self.tray_icon: self.tray_icon.showMessage( "智能关机助手", "程序已最小化到系统托盘,右键图标可退出", QSystemTrayIcon.Information, 2000 ) ========== 程序入口 ========== def main(): if platform.system() != "Windows": print("错误:此程序仅支持Windows系统!") sys.exit(1) WinAPI.request_admin() app = QApplication(sys.argv) app.setApplicationName("智能关机助手") try: ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("shutdown_helper") except: pass window = WindowsShutdownApp() window.show() sys.exit(app.exec_()) if name == "main": main()
2026年-6月-19日
173 阅读
0 评论
2026-5-19
pcl 模组
我用夸克网盘给你分享了「PCL 正式版 2.12.6」,点击链接或复制整段内容,打开「夸克APP」即可获取。/~445f3YeKqE~:/链接:https://pan.quark.cn/s/5615f91b86d4 文件夹里面也有模组,应该是安装好的 。直接点exe 的就行了
2026年-5月-19日
527 阅读
4 评论
科技好文
2026-3-22
全球学女娲,一起来补天2
想办法补窟窿 神话里的大窟窿,是天神共工弄的。南极洲的大窟窿,是谁干的? 呃,说来尴尬,科学研究表明,是人类自己。 人类造出的化学物质中,有几类便宜又好用,生活里几乎无处不在,冰箱里有,农药里有,灭火器里也有…… 可没想到的是,这些化学物质会跑到大气中,“吃”掉臭氧,南极洲的特殊环境,让他们更加贪婪。结果,臭氧层就被“吃”出了空间。 哎,女娲能熔炼五色石补天...
2026年-3月-22日
408 阅读
0 评论
科学
2026-3-22
微观科技新突破:当人类科技遇见看不见的微生物世界
提起科技革命,人们往往最先想到航天深空、人工智能、量子计算这些宏观领域的重磅突破,却常常忽略了藏在微观尺度的科技变革——以微生物为核心的微观科技,正在悄然改写农业、医疗、环保、能源乃至工业制造的底层逻辑。微生物作为地球上最古老、分布最广、数量最庞大的生命群体,过去因肉眼不可见被长期忽视,而随着显微技术、基因测序、合成生物学等前沿科技的迭代升级,人类终于打破了微观世界的壁垒,从被动认知微生物,走向主动操控、精准利用微生物的全新阶段,这股微观科技力量,也成为当下科技发展版图中不可替代的核心赛道。
2026年-3月-22日
450 阅读
0 评论
科技好文
2026-3-22
藏在泥土里的生命密码:微生物如何撑起地球生态的隐形脊梁
我们踩过的每一寸土地、捧起的每一把泥土,都绝非毫无生机的尘埃与砂砾。在肉眼无法窥见的微观世界里,数以万亿计的微生物正日夜不停运转,构成了地球生态系统最基础、最关键的隐形网络。它们是细菌、真菌、放线菌、古菌等微小生命的统称,单是一克肥沃的表层土壤中,微生物数量就能突破百亿,种类远超上万种。这些看似微不足道的小生命,没有惊天动地的外形,却掌控着地球物质循环、土壤肥力、植物生长乃至全球气候平衡的命脉,是当之无愧的“地球生态隐形脊梁”。 一、微观世界的“代谢工厂”:微生物的核心使命 在生态系统的能量与物质流转链条中,微生物扮演着独一无二的“分解者”与“转化者”角色,这也是它们最核心的生态功能。自然界中动植物的枯枝落叶、残体遗骸,若是没有微生物的分解作用,会层层堆积,让整个生态系统陷入停滞。微生物会分泌各类特殊酶类,将动植物残体中的复杂有机物,比如纤维素、木质素、蛋白质,逐步分解成二氧化碳、水和无机盐,这些物质又会重新回归土壤、空气与水体,成为植物生长的养分,完成生态系统的物质循环闭环。 除了分解作用,微生物还能完成很多高等生物无法实现的生化反应。比如根瘤菌能与豆科植物根系共生,将空气中无法被植物直接吸收的氮气,转化成植物可利用的氨态氮,这就是生物固氮作用,每年仅土壤微生物的固氮量,就占据了全球陆地生态系统固氮总量的60%以上,省去了大量人工氮肥的消耗。还有一类特殊的微生物,能降解土壤中的重金属残留、农药污染物,成为生态修复的“天然清洁工”,在治理土壤污染、修复退化生态方面,展现出极强的应用价值。 二、被忽视的危机:人类活动正在撕裂微观生态网 长久以来,人类的生产生活活动,正在悄无声息地破坏这份脆弱的微观生态平衡,而这种破坏带来的连锁反应,远比我们想象的更深远。现代农业中过度使用化肥农药,是伤害土壤微生物的头号元凶。化学农药在杀灭病虫害的同时,也无差别杀死了土壤中的有益微生物,导致土壤微生物群落结构单一化,原本丰富的菌种大量消亡,土壤逐渐失去自我修复能力,变得板结、贫瘠,陷入“越施化肥越贫瘠,越贫瘠越施肥”的恶性循环。 工业污染、生活垃圾渗漏、过度开垦与水土流失,同样在持续挤压微生物的生存空间。土壤板结会阻断空气与水分渗透,让好氧微生物大量死亡;酸雨降落改变土壤酸碱度,会直接破坏微生物的生存环境;森林砍伐、湿地填埋则让大量原生微生物失去栖息地,彻底从地球上消失。更值得警惕的是,微生物群落的失衡,会间接影响植物抗病能力、加剧温室效应——微生物分解有机物的过程能调节碳循环,菌群失衡会导致土壤碳储存能力下降,释放更多二氧化碳,进一步加剧全球气候变暖。 科学冷知识:地球上超过80%的微生物尚未被人类发现和命名,它们的生态功能、代谢机制依旧是未解之谜。每一种微生物的消亡,都意味着我们永久失去了一份潜在的科学资源,或许是新型抗生素的来源,或许是治理污染的关键菌种。 三、守护微观生命:从认知到行动的科学方案 守护土壤微生物,并非遥不可及的科研课题,而是普通人也能参与的生态行动,核心思路就是遵循自然规律,减少人为干预,帮助微观生态恢复自我平衡。 在农业领域,推广生态农业、有机种植是最有效的方式。用腐熟的有机肥替代化肥,用生物防治替代化学农药,实行轮作休耕、秸秆还田,秸秆还田能为微生物提供充足的有机养分,助力菌群快速繁殖,逐步恢复土壤活力。同时,种植绿肥植物、保护田间杂草,也能为微生物提供多样化的生存环境,维持菌群多样性。 对于普通大众而言,减少生活垃圾污染、节约用纸用电、支持有机农产品、拒绝过度使用化学清洁剂,都是在间接保护土壤与水体中的微生物。科研层面,科学家们正通过高通量测序、宏基因组技术,深入破译微生物的基因密码,筛选高效固氮、降解污染的有益菌种,研发微生物肥料、微生物修复剂,用科学手段助力生态修复。 四、微观生命带给我们的科学启示 微生物的存在,让我们重新理解生命的意义与生态的整体性。地球生态从来不是由大型动植物单独支撑的,那些渺小到看不见的生命,才是维系整个系统稳定的根基。这也印证了生态学的核心法则:万物共生,缺一不可,任何一个环节的缺失,都会引发整个生态链的连锁反应。 从微观微生物到宏观生态,从土壤健康到人类生存,科学研究不断证明,人与自然从来都是命运共同体。尊重每一种微小生命,守护好微观世界的平衡,本质上就是守护人类自身的生存家园。在探索宇宙浩瀚、钻研尖端科技的同时,我们更不该忘记低头看看脚下的泥土,那里藏着地球最古老的生命智慧,也藏着人类可持续发展的终极密码。
2026年-3月-22日
341 阅读
0 评论
科学
2026-3-22
全球学女娲,一起来补天
天上有个窟窿 呀!天怎么破了?好大一个窟窿! 几十年前,在南极洲,英国科学家有了大发现。 哟,他们也看中国神话,会讲《女娲补天》? 不不不,不是讲故事,南极洲的天上真的有一个大窟窿! 准确的说,不是天上,是高空中的臭氧层。臭氧层就像地球的防晒衣,挡住了99%的紫外线,保护了地球上所有的生物。 在准确点说,也不是大窟窿,是有片臭氧层格外稀薄。稀薄的臭氧层,就像防晒衣破了个口子,紫外线更容易钻进来。 这个发现,震惊全球。 天上有个大窟窿,在神话里会造成巨大的灾害,在现实中也会造成很大的灾难。紫外线多了,河里的小鱼小虾会被杀死等各种危害。 如果地球的防晒衣越来越破,天哪,地球会毁灭的!
2026年-3月-22日
318 阅读
0 评论
科学
1
2