最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python+PyQt5開發(fā)一個Windows電腦啟動項管理神器

 更新時間:2025年05月06日 14:19:56   作者:創(chuàng)客白澤  
這篇文章主要介紹了如何使用PyQt5開發(fā)一款顏值與功能并存的Windows啟動項管理工具,不僅能查看/刪除現(xiàn)有啟動項,還能智能添加新啟動項,支持拖拽操作,下面就跟隨小編一起了解一下吧

開篇:為什么我們需要啟動項管理工具

在日常使用Windows電腦時,你是否遇到過這些問題?

電腦開機越來越慢,像老牛拉破車

莫名其妙的后臺程序占用大量資源

想禁用某些啟動項卻找不到入口

需要添加自定義啟動項但操作復(fù)雜

今天,我將帶大家用PyQt5開發(fā)一款顏值與功能并存的Windows啟動項管理工具!不僅能查看/刪除現(xiàn)有啟動項,還能智能添加新啟動項,支持拖拽操作,界面美觀大方!

功能全景圖

先來看看我們開發(fā)的工具具備哪些殺手級功能:

? 雙模式啟動項查看

  • 當(dāng)前用戶啟動項(HKCU)
  • 所有用戶啟動項(HKLM)
  • 啟動文件夾項目

? 智能分類展示

  • 名稱/狀態(tài)/路徑/參數(shù) 四維信息
  • 樹形結(jié)構(gòu)清晰明了

? 三種添加方式

  • 拖拽文件快捷添加(超方便?。?/li>
  • 表單手動填寫添加
  • 瀏覽文件選擇添加

? 多位置支持

  • 當(dāng)前用戶注冊表
  • 所有用戶注冊表(需管理員權(quán)限)
  • 啟動文件夾

? 右鍵快捷操作

一鍵刪除不需要的啟動項

核心技術(shù)解析

1. Windows注冊表操作

我們通過Python的winreg模塊訪問Windows注冊表:

import winreg

???????# 讀取當(dāng)前用戶啟動項
def load_registry_startup_items(self, parent_item, hive, subkey):
    try:
        with winreg.OpenKey(hive, subkey) as key:
            i = 0
            while True:
                try:
                    name, value, _ = winreg.EnumValue(key, i)
                    # 解析注冊表值
                    path, args = self.parse_command(value)
                    # 創(chuàng)建樹形項目...
                    i += 1
                except OSError:
                    break

關(guān)鍵點:

  • HKEY_CURRENT_USER - 當(dāng)前用戶配置
  • HKEY_LOCAL_MACHINE - 所有用戶配置
  • EnumValue - 枚舉注冊表值
  • SetValueEx - 寫入新值

2. 啟動文件夾處理

除了注冊表,Windows還會從兩個特殊文件夾加載啟動項:

# 獲取啟動文件夾路徑
user_startup = os.path.join(os.getenv('APPDATA'), 
                          r'Microsoft\Windows\Start Menu\Programs\Startup')
all_users_startup = os.path.join(os.getenv('ProgramData'),
                               r'Microsoft\Windows\Start Menu\Programs\Startup')

對于.lnk快捷方式,我們使用win32com解析真實路徑:

from win32com.client import Dispatch

???????shell = Dispatch('WScript.Shell')
shortcut = shell.CreateShortCut(item_path)
target_path = shortcut.TargetPath  # 獲取實際目標(biāo)

UI設(shè)計美學(xué)

我們的工具采用紫色系漸變風(fēng)格,看起來專業(yè)又不失活潑:

1. 全局樣式設(shè)置

def set_style(self):
    palette = QPalette()
    palette.setColor(QPalette.Window, QColor(250, 245, 255))  # 淺紫色背景
    palette.setColor(QPalette.Highlight, QColor(138, 43, 226))  # 紫羅蘭選中色
    QApplication.setPalette(palette)
    
    # 精致按鈕樣式
    button_style = """
    QPushButton {
        background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                                  stop:0 #e6e6fa, stop:1 #d8bfd8);
        border: 1px solid #9370db;
        border-radius: 6px;
        padding: 8px 15px;
        color: #4b0082;
    }
    """
    self.setStyleSheet(button_style)

2. 創(chuàng)新UI元素

拖拽添加區(qū)域:

def create_drop_area(self, layout):
    drop_group = QGroupBox("拖拽添加 (將文件拖到此處)")
    drop_group.setAcceptDrops(True)
    drop_group.dragEnterEvent = self.drag_enter_event
    drop_group.dropEvent = self.drop_event
    
    # 添加圖標(biāo)和提示文本...

選項卡設(shè)計:

self.tabs = QTabWidget()
self.tabs.setTabPosition(QTabWidget.North)
self.tabs.setDocumentMode(True)
self.tabs.setStyleSheet("""
    QTabBar::tab {
        padding: 10px 20px;
        background: qlineargradient(...);
        border: 1px solid #9370db;
    }
""")

完整源碼剖析

由于源碼較長(約500行),這里重點分析幾個核心部分:

1. 主窗口結(jié)構(gòu)

class StartupManager(QMainWindow):
    def __init__(self):
        super().__init__()
        # 窗口基本設(shè)置
        self.setWindowTitle("電腦啟動項管理工具")
        self.setGeometry(100, 100, 1000, 750)
        
        # 初始化UI
        self.set_style()
        self.init_ui()
        
        # 加載數(shù)據(jù)
        self.load_startup_items()

2. 啟動項加載邏輯

def load_startup_items(self):
    self.tree.clear()
    
    # 1. 加載注冊表啟動項
    user_item = QTreeWidgetItem(["當(dāng)前用戶啟動項"])
    self.load_registry_startup_items(user_item, winreg.HKEY_CURRENT_USER, ...)
    
    # 2. 加載啟動文件夾
    folder_item = QTreeWidgetItem(["啟動文件夾項目"])
    self.load_startup_folder_items(folder_item)

3. 添加新啟動項

def add_manual_startup_item(self):
    # 獲取表單數(shù)據(jù)
    name = self.name_input.text()
    path = self.path_input.text()
    
    # 驗證輸入
    if not name or not path:
        QMessageBox.warning("名稱和路徑不能為空")
        return
    
    # 根據(jù)選擇的位置執(zhí)行添加
    if self.location_radio_all.isChecked():
        # 寫入HKLM注冊表(需要管理員權(quán)限)
    elif self.location_radio_folder.isChecked():
        # 創(chuàng)建快捷方式到啟動文件夾
    else:
        # 寫入HKCU注冊表

完整源碼下載

 import os
import sys
import winreg
from PyQt5.QtWidgets import (QApplication, QMainWindow, QTreeWidget, QTreeWidgetItem, 
                             QVBoxLayout, QWidget, QHeaderView, QMenu, QFileDialog,
                             QAbstractItemView, QMessageBox, QLabel, QPushButton, 
                             QHBoxLayout, QTabWidget, QGroupBox, QFormLayout, QLineEdit,
                             QFrame, QScrollArea, QStyle)
from PyQt5.QtCore import Qt, QMimeData, QSize
from PyQt5.QtGui import QIcon, QPalette, QColor, QFont, QPixmap

class StartupManager(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("電腦啟動項管理工具")
        self.setWindowIcon(self.style().standardIcon(QStyle.SP_ComputerIcon))
        self.setGeometry(100, 100, 1000, 750)
        
        # 設(shè)置應(yīng)用樣式
        self.set_style()
        
        self.init_ui()
        self.load_startup_items()
        
    def set_style(self):
        # 設(shè)置多彩配色方案
        palette = QPalette()
        palette.setColor(QPalette.Window, QColor(250, 245, 255))
        palette.setColor(QPalette.WindowText, QColor(80, 80, 80))
        palette.setColor(QPalette.Base, QColor(255, 255, 255))
        palette.setColor(QPalette.AlternateBase, QColor(245, 245, 255))
        palette.setColor(QPalette.ToolTipBase, QColor(255, 255, 255))
        palette.setColor(QPalette.ToolTipText, QColor(80, 80, 80))
        palette.setColor(QPalette.Text, QColor(80, 80, 80))
        palette.setColor(QPalette.Button, QColor(230, 230, 250))
        palette.setColor(QPalette.ButtonText, QColor(80, 80, 80))
        palette.setColor(QPalette.BrightText, QColor(255, 255, 255))
        palette.setColor(QPalette.Highlight, QColor(138, 43, 226))  # 紫羅蘭色
        palette.setColor(QPalette.HighlightedText, QColor(255, 255, 255))
        QApplication.setPalette(palette)
        
        # 設(shè)置全局樣式表
        style = """
        QMainWindow {
            background: qlineargradient(x1:0, y1:0, x2:1, y2:1,
                                      stop:0 #faf5ff, stop:1 #e6e6fa);
        }
        QTreeWidget {
            border: 2px solid #d8bfd8;
            border-radius: 8px;
            background-color: white;
            padding: 5px;
        }
        QTreeWidget::item {
            padding: 5px;
        }
        QTreeWidget::item:hover {
            background: #e6e6fa;
        }
        QGroupBox {
            border: 2px solid #d8bfd8;
            border-radius: 8px;
            margin-top: 15px;
            padding-top: 20px;
            background: rgba(255, 255, 255, 0.8);
        }
        QGroupBox::title {
            subcontrol-origin: margin;
            left: 15px;
            padding: 0 5px;
            color: #9370db;
            font-weight: bold;
        }
        QPushButton {
            background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                                      stop:0 #e6e6fa, stop:1 #d8bfd8);
            border: 1px solid #9370db;
            border-radius: 6px;
            padding: 8px 15px;
            min-width: 100px;
            color: #4b0082;
            font-weight: bold;
        }
        QPushButton:hover {
            background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                                      stop:0 #d8bfd8, stop:1 #e6e6fa);
        }
        QPushButton:pressed {
            background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                                      stop:0 #9370db, stop:1 #d8bfd8);
            color: white;
        }
        QLineEdit {
            border: 1px solid #d8bfd8;
            border-radius: 6px;
            padding: 8px;
            background: white;
        }
        QTabWidget::pane {
            border: 2px solid #d8bfd8;
            border-radius: 8px;
            background: rgba(255, 255, 255, 0.9);
            margin: 5px;
        }
        QTabBar::tab {
            padding: 10px 20px;
            background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                                      stop:0 #e6e6fa, stop:1 #d8bfd8);
            border: 1px solid #9370db;
            border-bottom: none;
            border-top-left-radius: 8px;
            border-top-right-radius: 8px;
            color: #4b0082;
            font-weight: bold;
        }
        QTabBar::tab:selected {
            background: white;
            margin-bottom: -1px;
        }
        QTabBar::tab:hover {
            background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                                      stop:0 #d8bfd8, stop:1 #e6e6fa);
        }
        QHeaderView::section {
            background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                                      stop:0 #e6e6fa, stop:1 #d8bfd8);
            padding: 5px;
            border: 1px solid #9370db;
            color: #4b0082;
            font-weight: bold;
        }
        QScrollArea {
            border: none;
            background: transparent;
        }
        """
        self.setStyleSheet(style)
        
    def init_ui(self):
        # 主窗口部件
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        
        # 主布局
        main_layout = QVBoxLayout(central_widget)
        main_layout.setContentsMargins(15, 15, 15, 15)
        main_layout.setSpacing(15)
        
        # 創(chuàng)建標(biāo)題欄
        self.create_title_bar(main_layout)
        
        # 創(chuàng)建選項卡
        self.tabs = QTabWidget()
        self.tabs.setTabPosition(QTabWidget.North)
        self.tabs.setDocumentMode(True)
        main_layout.addWidget(self.tabs)
        
        # 創(chuàng)建"查看啟動項"標(biāo)簽頁
        self.create_view_tab()
        
        # 創(chuàng)建"添加啟動項"標(biāo)簽頁
        self.create_add_tab()
        
        # 創(chuàng)建狀態(tài)欄
        self.statusBar().showMessage("就緒")
        
    def create_title_bar(self, layout):
        # 標(biāo)題欄布局
        title_layout = QHBoxLayout()
        
        # 圖標(biāo)
        icon_label = QLabel()
        icon_pixmap = self.style().standardIcon(QStyle.SP_ComputerIcon).pixmap(48, 48)
        icon_label.setPixmap(icon_pixmap)
        title_layout.addWidget(icon_label)
        
        # 標(biāo)題和副標(biāo)題
        text_layout = QVBoxLayout()
        title_label = QLabel("電腦啟動項管理")
        title_label.setStyleSheet("font-size: 24px; font-weight: bold; color: #9370db;")
        subtitle_label = QLabel("輕松管理系統(tǒng)啟動項")
        subtitle_label.setStyleSheet("font-size: 14px; color: #9370db;")
        text_layout.addWidget(title_label)
        text_layout.addWidget(subtitle_label)
        title_layout.addLayout(text_layout)
        
        title_layout.addStretch()
        
        # 刷新按鈕
        refresh_btn = QPushButton()
        refresh_btn.setIcon(self.style().standardIcon(QStyle.SP_BrowserReload))
        refresh_btn.setIconSize(QSize(24, 24))
        refresh_btn.setToolTip("刷新列表")
        refresh_btn.clicked.connect(self.load_startup_items)
        refresh_btn.setFixedSize(40, 40)
        title_layout.addWidget(refresh_btn)
        
        layout.addLayout(title_layout)
        
        # 添加分隔線
        separator = QFrame()
        separator.setFrameShape(QFrame.HLine)
        separator.setFrameShadow(QFrame.Sunken)
        separator.setStyleSheet("color: #d8bfd8;")
        layout.addWidget(separator)
    
    def create_view_tab(self):
        # 查看啟動項標(biāo)簽頁
        view_tab = QWidget()
        layout = QVBoxLayout(view_tab)
        layout.setContentsMargins(10, 10, 10, 10)
        layout.setSpacing(10)
        
        # 樹形列表
        self.tree = QTreeWidget()
        self.tree.setColumnCount(4)
        self.tree.setHeaderLabels(["名稱", "狀態(tài)", "命令行/路徑", "參數(shù)"])
        self.tree.setSelectionMode(QAbstractItemView.SingleSelection)
        self.tree.setContextMenuPolicy(Qt.CustomContextMenu)
        self.tree.customContextMenuRequested.connect(self.show_context_menu)
        
        # 設(shè)置列寬
        self.tree.header().setSectionResizeMode(0, QHeaderView.ResizeToContents)
        self.tree.header().setSectionResizeMode(1, QHeaderView.ResizeToContents)
        self.tree.header().setSectionResizeMode(2, QHeaderView.Stretch)
        self.tree.header().setSectionResizeMode(3, QHeaderView.ResizeToContents)
        
        # 添加到滾動區(qū)域
        scroll_area = QScrollArea()
        scroll_area.setWidgetResizable(True)
        scroll_area.setWidget(self.tree)
        layout.addWidget(scroll_area)
        
        self.tabs.addTab(view_tab, "查看啟動項")
    
    def create_add_tab(self):
        # 添加啟動項標(biāo)簽頁
        add_tab = QWidget()
        layout = QVBoxLayout(add_tab)
        layout.setContentsMargins(15, 15, 15, 15)
        layout.setSpacing(15)
        
        # 創(chuàng)建拖拽區(qū)域
        self.create_drop_area(layout)
        
        # 創(chuàng)建表單區(qū)域
        self.create_form_area(layout)
        
        self.tabs.addTab(add_tab, "添加啟動項")
    
    def create_drop_area(self, layout):
        # 拖拽區(qū)域
        drop_group = QGroupBox("拖拽添加 (將文件拖到此處)")
        drop_group.setAcceptDrops(True)
        drop_group.dragEnterEvent = self.drag_enter_event
        drop_group.dropEvent = lambda e: self.drop_event(e, drop_group)
        
        drop_layout = QVBoxLayout(drop_group)
        drop_layout.setContentsMargins(20, 20, 20, 20)
        drop_layout.setSpacing(20)
        
        # 圖標(biāo)
        drop_icon = QLabel()
        drop_icon.setPixmap(self.style().standardIcon(QStyle.SP_FileIcon).pixmap(64, 64))
        drop_icon.setAlignment(Qt.AlignCenter)
        drop_layout.addWidget(drop_icon)
        
        # 文本
        drop_label = QLabel("拖拽可執(zhí)行文件或快捷方式到此處")
        drop_label.setAlignment(Qt.AlignCenter)
        drop_label.setStyleSheet("""
            font-size: 16px; 
            font-weight: bold; 
            color: #9370db;
        """)
        drop_layout.addWidget(drop_label)
        
        # 提示
        drop_hint = QLabel("支持 .exe, .lnk, .bat, .cmd 文件")
        drop_hint.setAlignment(Qt.AlignCenter)
        drop_hint.setStyleSheet("font-size: 12px; color: #9370db;")
        drop_layout.addWidget(drop_hint)
        
        layout.addWidget(drop_group)
    
    def create_form_area(self, layout):
        # 表單區(qū)域
        form_group = QGroupBox("手動添加")
        form_layout = QFormLayout(form_group)
        form_layout.setContentsMargins(15, 15, 15, 15)
        form_layout.setSpacing(15)
        form_layout.setLabelAlignment(Qt.AlignRight)
        
        # 名稱輸入
        self.name_input = QLineEdit()
        self.name_input.setPlaceholderText("輸入啟動項名稱")
        form_layout.addRow("名稱:", self.name_input)
        
        # 路徑輸入
        path_layout = QHBoxLayout()
        self.path_input = QLineEdit()
        self.path_input.setPlaceholderText("選擇或輸入程序路徑")
        browse_btn = QPushButton("瀏覽...")
        browse_btn.setIcon(self.style().standardIcon(QStyle.SP_DirOpenIcon))
        browse_btn.clicked.connect(self.browse_file)
        path_layout.addWidget(self.path_input)
        path_layout.addWidget(browse_btn)
        form_layout.addRow("路徑:", path_layout)
        
        # 參數(shù)輸入
        self.args_input = QLineEdit()
        self.args_input.setPlaceholderText("可選參數(shù)")
        form_layout.addRow("參數(shù):", self.args_input)
        
        layout.addWidget(form_group)
        
        # 添加位置選擇
        self.create_location_selector(layout)
        
        # 添加按鈕
        add_btn = QPushButton("添加啟動項")
        add_btn.setIcon(self.style().standardIcon(QStyle.SP_DialogOkButton))
        add_btn.clicked.connect(self.add_manual_startup_item)
        add_btn.setStyleSheet("""
            background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                                      stop:0 #9370db, stop:1 #8a2be2);
            color: white;
            font-size: 16px;
            padding: 12px;
        """)
        layout.addWidget(add_btn)
        
        layout.addStretch()
    
    def create_location_selector(self, layout):
        # 位置選擇器
        location_group = QGroupBox("添加位置")
        location_layout = QHBoxLayout(location_group)
        location_layout.setSpacing(20)
        
        # 當(dāng)前用戶選項
        self.location_radio_user = QPushButton("當(dāng)前用戶")
        self.location_radio_user.setCheckable(True)
        self.location_radio_user.setChecked(True)
        self.location_radio_user.setIcon(self.style().standardIcon(QStyle.SP_ComputerIcon))
        self.location_radio_user.setStyleSheet("""
            QPushButton {
                background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                                          stop:0 #e6e6fa, stop:1 #d8bfd8);
                border: 2px solid #9370db;
                border-radius: 6px;
                padding: 10px;
            }
            QPushButton:checked {
                background: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                                          stop:0 #9370db, stop:1 #8a2be2);
                color: white;
            }
        """)
        
        # 所有用戶選項
        self.location_radio_all = QPushButton("所有用戶")
        self.location_radio_all.setCheckable(True)
        self.location_radio_all.setIcon(self.style().standardIcon(QStyle.SP_DesktopIcon))
        self.location_radio_all.setStyleSheet(self.location_radio_user.styleSheet())
        
        # 啟動文件夾選項
        self.location_radio_folder = QPushButton("啟動文件夾")
        self.location_radio_folder.setCheckable(True)
        self.location_radio_folder.setIcon(self.style().standardIcon(QStyle.SP_DirIcon))
        self.location_radio_folder.setStyleSheet(self.location_radio_user.styleSheet())
        
        location_layout.addWidget(self.location_radio_user)
        location_layout.addWidget(self.location_radio_all)
        location_layout.addWidget(self.location_radio_folder)
        
        layout.addWidget(location_group)
    
    def load_startup_items(self):
        self.tree.clear()
        
        # 加載當(dāng)前用戶的啟動項
        user_item = QTreeWidgetItem(self.tree, ["當(dāng)前用戶啟動項", "", "", ""])
        user_item.setExpanded(True)
        self.load_registry_startup_items(user_item, winreg.HKEY_CURRENT_USER,
                                      r"Software\Microsoft\Windows\CurrentVersion\Run")
        
        # 加載所有用戶的啟動項
        all_users_item = QTreeWidgetItem(self.tree, ["所有用戶啟動項", "", "", ""])
        all_users_item.setExpanded(True)
        self.load_registry_startup_items(all_users_item, winreg.HKEY_LOCAL_MACHINE,
                                       r"Software\Microsoft\Windows\CurrentVersion\Run")
        
        # 加載啟動文件夾中的項目
        startup_folder_item = QTreeWidgetItem(self.tree, ["啟動文件夾項目", "", "", ""])
        startup_folder_item.setExpanded(True)
        self.load_startup_folder_items(startup_folder_item)
        
        # 切換到查看標(biāo)簽頁
        self.tabs.setCurrentIndex(0)
        self.statusBar().showMessage("啟動項列表已刷新", 3000)
    
    def load_registry_startup_items(self, parent_item, hive, subkey):
        try:
            with winreg.OpenKey(hive, subkey) as key:
                i = 0
                while True:
                    try:
                        name, value, _ = winreg.EnumValue(key, i)
                        # 解析值和參數(shù)
                        path, args = self.parse_command(value)
                        
                        item = QTreeWidgetItem(parent_item)
                        item.setText(0, name)
                        item.setText(1, "已啟用")
                        item.setText(2, path)
                        item.setText(3, args)
                        
                        # 存儲額外信息用于刪除
                        item.setData(0, Qt.UserRole, ("registry", hive, subkey, name))
                        
                        i += 1
                    except OSError:
                        break
        except WindowsError:
            pass
    
    def load_startup_folder_items(self, parent_item):
        # 獲取當(dāng)前用戶的啟動文件夾
        user_startup = os.path.join(os.getenv('APPDATA'), 
                                  r'Microsoft\Windows\Start Menu\Programs\Startup')
        self.load_folder_items(parent_item, user_startup, "user")
        
        # 獲取所有用戶的啟動文件夾
        all_users_startup = os.path.join(os.getenv('ProgramData'),
                                       r'Microsoft\Windows\Start Menu\Programs\Startup')
        self.load_folder_items(parent_item, all_users_startup, "all_users")
    
    def load_folder_items(self, parent_item, folder_path, folder_type):
        if not os.path.exists(folder_path):
            return
            
        for item_name in os.listdir(folder_path):
            item_path = os.path.join(folder_path, item_name)
            
            # 如果是快捷方式,解析目標(biāo)
            if item_name.lower().endswith('.lnk'):
                try:
                    from win32com.client import Dispatch
                    shell = Dispatch('WScript.Shell')
                    shortcut = shell.CreateShortCut(item_path)
                    target_path = shortcut.TargetPath
                    arguments = shortcut.Arguments
                    working_dir = shortcut.WorkingDirectory
                    
                    # 構(gòu)建完整路徑
                    full_path = target_path
                    if working_dir:
                        full_path = os.path.join(working_dir, target_path)
                    
                    item = QTreeWidgetItem(parent_item)
                    item.setText(0, os.path.splitext(item_name)[0])
                    item.setText(1, "已啟用")
                    item.setText(2, full_path)
                    item.setText(3, arguments)
                    
                    # 存儲額外信息用于刪除
                    item.setData(0, Qt.UserRole, ("folder", folder_path, item_name))
                except:
                    # 如果解析快捷方式失敗,直接顯示路徑
                    item = QTreeWidgetItem(parent_item)
                    item.setText(0, os.path.splitext(item_name)[0])
                    item.setText(1, "已啟用")
                    item.setText(2, item_path)
                    item.setText(3, "")
                    item.setData(0, Qt.UserRole, ("folder", folder_path, item_name))
            else:
                # 普通文件
                item = QTreeWidgetItem(parent_item)
                item.setText(0, item_name)
                item.setText(1, "已啟用")
                item.setText(2, item_path)
                item.setText(3, "")
                item.setData(0, Qt.UserRole, ("folder", folder_path, item_name))
    
    def parse_command(self, command):
        # 簡單的命令解析,分離路徑和參數(shù)
        if command.startswith('"'):
            # 處理帶引號的路徑
            end_quote = command.find('"', 1)
            if end_quote != -1:
                path = command[1:end_quote]
                args = command[end_quote+1:].strip()
                return path, args
        else:
            # 不帶引號的路徑
            space_pos = command.find(' ')
            if space_pos != -1:
                return command[:space_pos], command[space_pos+1:].strip()
        
        # 沒有參數(shù)的情況
        return command, ""
    
    def show_context_menu(self, position):
        item = self.tree.itemAt(position)
        if not item or not item.parent():
            return
            
        menu = QMenu()
        delete_action = menu.addAction("刪除啟動項")
        delete_action.setIcon(self.style().standardIcon(QStyle.SP_TrashIcon))
        delete_action.triggered.connect(lambda: self.delete_startup_item(item))
        menu.exec_(self.tree.viewport().mapToGlobal(position))
    
    def delete_startup_item(self, item):
        item_type, *item_data = item.data(0, Qt.UserRole)
        
        reply = QMessageBox.question(self, '確認刪除', 
                                    '確定要刪除這個啟動項嗎?', 
                                    QMessageBox.Yes | QMessageBox.No, 
                                    QMessageBox.No)
        
        if reply == QMessageBox.Yes:
            try:
                if item_type == "registry":
                    hive, subkey, name = item_data
                    with winreg.OpenKey(hive, subkey, 0, winreg.KEY_WRITE) as key:
                        winreg.DeleteValue(key, name)
                elif item_type == "folder":
                    folder_path, item_name = item_data
                    os.remove(os.path.join(folder_path, item_name))
                
                # 從樹中移除
                item.parent().removeChild(item)
                QMessageBox.information(self, "成功", "啟動項已刪除")
                self.statusBar().showMessage("啟動項已刪除", 3000)
            except Exception as e:
                QMessageBox.critical(self, "錯誤", f"刪除失敗: {str(e)}")
                self.statusBar().showMessage(f"刪除失敗: {str(e)}", 3000)
    
    def browse_file(self):
        file_path, _ = QFileDialog.getOpenFileName(
            self, "選擇可執(zhí)行文件", "", 
            "可執(zhí)行文件 (*.exe *.bat *.cmd);;快捷方式 (*.lnk);;所有文件 (*.*)")
        
        if file_path:
            self.path_input.setText(file_path)
            if not self.name_input.text():
                # 自動填充名稱
                name = os.path.splitext(os.path.basename(file_path))[0]
                self.name_input.setText(name)
            self.statusBar().showMessage(f"已選擇文件: {file_path}", 3000)
    
    def drag_enter_event(self, event):
        if event.mimeData().hasUrls():
            event.acceptProposedAction()
    
    def drop_event(self, event, drop_group):
        urls = event.mimeData().urls()
        if urls:
            file_path = urls[0].toLocalFile()
            if file_path.lower().endswith(('.exe', '.lnk', '.bat', '.cmd')):
                # 更新UI顯示
                drop_label = drop_group.findChild(QLabel)
                drop_label.setText(f"已選擇: {os.path.basename(file_path)}")
                drop_label.setStyleSheet("""
                    font-size: 16px; 
                    font-weight: bold; 
                    color: #8a2be2;
                """)
                
                # 自動填充表單
                self.path_input.setText(file_path)
                if not self.name_input.text():
                    name = os.path.splitext(os.path.basename(file_path))[0]
                    self.name_input.setText(name)
                
                event.acceptProposedAction()
                self.statusBar().showMessage(f"已拖入文件: {file_path}", 3000)
    
    def add_manual_startup_item(self):
        name = self.name_input.text().strip()
        path = self.path_input.text().strip()
        args = self.args_input.text().strip()
        
        if not name or not path:
            QMessageBox.warning(self, "警告", "名稱和路徑不能為空")
            self.statusBar().showMessage("錯誤: 名稱和路徑不能為空", 3000)
            return
            
        if not os.path.exists(path):
            QMessageBox.warning(self, "警告", "指定的路徑不存在")
            self.statusBar().showMessage("錯誤: 指定的路徑不存在", 3000)
            return
        
        # 確定添加位置
        location = "user"
        if self.location_radio_all.isChecked():
            location = "all_users"
        elif self.location_radio_folder.isChecked():
            location = "folder"
        
        try:
            if location in ["user", "all_users"]:
                # 添加到注冊表
                hive = winreg.HKEY_CURRENT_USER if location == "user" else winreg.HKEY_LOCAL_MACHINE
                subkey = r"Software\Microsoft\Windows\CurrentVersion\Run"
                
                # 構(gòu)建完整命令
                command = f'"{path}"' if ' ' in path else path
                if args:
                    command += f" {args}"
                
                try:
                    with winreg.OpenKey(hive, subkey, 0, winreg.KEY_WRITE) as key:
                        winreg.SetValueEx(key, name, 0, winreg.REG_SZ, command)
                except PermissionError:
                    QMessageBox.critical(self, "錯誤", "需要管理員權(quán)限才能添加所有用戶啟動項")
                    self.statusBar().showMessage("錯誤: 需要管理員權(quán)限", 3000)
                    return
            else:
                # 添加到啟動文件夾
                startup_folder = os.path.join(os.getenv('APPDATA'), 
                                           r'Microsoft\Windows\Start Menu\Programs\Startup')
                
                # 如果是快捷方式,直接復(fù)制
                if path.lower().endswith('.lnk'):
                    import shutil
                    shutil.copy(path, os.path.join(startup_folder, f"{name}.lnk"))
                else:
                    # 創(chuàng)建快捷方式
                    try:
                        from win32com.client import Dispatch
                        shell = Dispatch('WScript.Shell')
                        shortcut = shell.CreateShortCut(
                            os.path.join(startup_folder, f"{name}.lnk"))
                        shortcut.TargetPath = path
                        shortcut.Arguments = args
                        shortcut.WorkingDirectory = os.path.dirname(path)
                        shortcut.save()
                    except:
                        QMessageBox.critical(self, "錯誤", "無法創(chuàng)建快捷方式")
                        self.statusBar().showMessage("錯誤: 無法創(chuàng)建快捷方式", 3000)
                        return
            
            QMessageBox.information(self, "成功", "啟動項已添加")
            
            # 清空表單
            self.name_input.clear()
            self.path_input.clear()
            self.args_input.clear()
            
            # 重置拖拽區(qū)域
            drop_group = self.findChild(QGroupBox, "拖拽添加")
            if drop_group:
                drop_label = drop_group.findChild(QLabel)
                drop_label.setText("拖拽可執(zhí)行文件或快捷方式到此處")
                drop_label.setStyleSheet("""
                    font-size: 16px; 
                    font-weight: bold; 
                    color: #9370db;
                """)
            
            # 刷新列表
            self.load_startup_items()
            self.statusBar().showMessage("啟動項已成功添加", 3000)
            
        except Exception as e:
            QMessageBox.critical(self, "錯誤", f"添加失敗: {str(e)}")
            self.statusBar().showMessage(f"添加失敗: {str(e)}", 3000)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    
    # 設(shè)置應(yīng)用程序字體
    font = QFont("微軟雅黑", 10)
    app.setFont(font)
    
    window = StartupManager()
    window.show()
    sys.exit(app.exec_())

擴展思考

我們的工具還可以進一步優(yōu)化:

1.啟動延遲設(shè)置:通過/delay參數(shù)或任務(wù)計劃程序?qū)崿F(xiàn)分批啟動

2.啟動影響評估:監(jiān)控各啟動項的資源占用情況

3.云同步功能:將配置保存到云端,多設(shè)備同步

4.黑白名單機制:自動識別可疑啟動項

5.管理員權(quán)限自動提權(quán):使用ctypes調(diào)用ShellExecute以管理員身份運行

import ctypes
ctypes.windll.shell32.ShellExecuteW(None, "runas", sys.executable, __file__, None, 1)

總結(jié)

通過本項目,我們學(xué)到了:

  • PyQt5高級UI開發(fā) - 自定義樣式、復(fù)雜布局、拖放功能
  • Windows注冊表操作 - 安全讀寫系統(tǒng)關(guān)鍵配置
  • 系統(tǒng)工具開發(fā)思路 - 從用戶需求出發(fā)設(shè)計功能
  • 異常處理重要性 - 特別是涉及系統(tǒng)級操作時

完整代碼已在上文提供,建議大家:

  • 先理解核心邏輯
  • 分段測試各個功能模塊
  • 嘗試添加自己的創(chuàng)新功能

以上就是Python+PyQt5開發(fā)一個Windows電腦啟動項管理神器的詳細內(nèi)容,更多關(guān)于Python電腦啟動項管理的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Pandas中inf值替換的方法

    Pandas中inf值替換的方法

    本文主要介紹了Pandas中inf值替換的方法,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • 使用Python實現(xiàn)查找并替換PDF中的文本

    使用Python實現(xiàn)查找并替換PDF中的文本

    在處理 PDF 文檔時,經(jīng)常需要查找特定文本并將其替換為新內(nèi)容,本文將深入探討如何使用 Python 實現(xiàn)多種場景下的 PDF 文本查找與替換功能,有需要的可以了解下
    2026-03-03
  • Python3+Pycharm+PyQt5環(huán)境搭建步驟圖文詳解

    Python3+Pycharm+PyQt5環(huán)境搭建步驟圖文詳解

    這篇文章主要介紹了Python3+Pycharm+PyQt5環(huán)境搭建步驟圖文詳解,本文給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-05-05
  • Python使用matplotlib實現(xiàn)的圖像讀取、切割裁剪功能示例

    Python使用matplotlib實現(xiàn)的圖像讀取、切割裁剪功能示例

    這篇文章主要介紹了Python使用matplotlib實現(xiàn)的圖像讀取、切割裁剪功能,結(jié)合實例形式分析了Python基于matplotlib操作圖片的加載、讀取、坐標(biāo)控制及裁剪相關(guān)操作技巧,需要的朋友可以參考下
    2018-04-04
  • Python實現(xiàn)非正太分布的異常值檢測方式

    Python實現(xiàn)非正太分布的異常值檢測方式

    今天小編就為大家分享一篇Python實現(xiàn)非正太分布的異常值檢測方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2019-12-12
  • Python簡單計算文件夾大小的方法

    Python簡單計算文件夾大小的方法

    這篇文章主要介紹了Python簡單計算文件夾大小的方法,涉及Python針對目錄的遍歷與文件計算的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-07-07
  • 解決安裝pytorch運行import torch出錯ModuleNotFoundError:No module named'torch'問題

    解決安裝pytorch運行import torch出錯ModuleNotFoundError:No 

    安裝PyTorch時遇到`ModuleNotFoundError: No module named 'torch'`錯誤,通常是由于Python版本不匹配或conda未升級導(dǎo)致的,解決方法是安裝特定版本的PyTorch,并使用以下代碼檢查安裝是否成功
    2025-12-12
  • Python實現(xiàn)打印詳細報錯日志,獲取報錯信息位置行數(shù)

    Python實現(xiàn)打印詳細報錯日志,獲取報錯信息位置行數(shù)

    這篇文章主要介紹了Python實現(xiàn)打印詳細報錯日志,獲取報錯信息位置行數(shù)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • Python使用Turtle實現(xiàn)精確計時工具

    Python使用Turtle實現(xiàn)精確計時工具

    這篇文章主要為大家詳細介紹了Python如何使用Turtle實現(xiàn)精確計時工具,文中的示例代碼講解詳細,具有一定的借鑒價值,有需要的小伙伴可以參考一下
    2025-05-05
  • 使用Python打造帶類別標(biāo)簽的三維柱狀圖

    使用Python打造帶類別標(biāo)簽的三維柱狀圖

    帶類別標(biāo)簽的三維柱狀圖是一種在三維空間中展示分類數(shù)據(jù)的可視化工具,下面小編就來和大家詳細介紹一下如何使用Python打造帶類別標(biāo)簽的三維柱狀圖吧
    2025-07-07

最新評論

遵化市| 江华| 邵东县| 芮城县| 汶上县| 池州市| 大丰市| 新巴尔虎左旗| 大厂| 南开区| 裕民县| 化州市| 龙川县| 无为县| 榆社县| 西畴县| 万安县| 汽车| 江阴市| 阿瓦提县| 临洮县| 神池县| 项城市| 祥云县| 防城港市| 邵武市| 大关县| 泰安市| 麟游县| 长兴县| 奉新县| 中牟县| 古浪县| 垦利县| 进贤县| 封丘县| 淅川县| 舒城县| 大丰市| 富锦市| 集安市|