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

Python+PyQt5打造炫酷的桌面快捷方式管理器

 更新時間:2026年03月11日 09:41:59   作者:創(chuàng)客白澤  
這篇文章主要為大家詳細(xì)介紹了如何基于Python+PyQt5打造炫酷的桌面快捷方式管理器,可以實現(xiàn)多主題切換,動畫效果和跨平臺支持,感興趣的小伙伴可以了解下

本文亮點:基于PyQt5+Emoji實現(xiàn)多主題切換、動畫效果、跨平臺支持的桌面快捷方式管理器,3000字詳解開發(fā)全流程!

項目概述

在Windows/macOS/Linux系統(tǒng)中,我們經(jīng)常需要快速訪問常用程序和文件夾。傳統(tǒng)方式是在桌面創(chuàng)建大量快捷方式,但會導(dǎo)致桌面雜亂無章。本項目使用PyQt5開發(fā)一個可視化快捷方式管理器,具有以下特點:

  • 4種精美主題:深色/淺色/紫色/漸變風(fēng)格
  • 現(xiàn)代化UI:帶動畫效果的按鈕、卡片式布局
  • 跨平臺支持:適配Windows/macOS/Linux
  • Emoji集成:讓界面更生動有趣
  • 實用功能:添加/打開/刪除/創(chuàng)建桌面快捷方式

圖1:系統(tǒng)架構(gòu)圖

功能特色

多主題切換系統(tǒng)

class ThemeManager:
    THEMES = {
        "dark": {"name": "?? 深色主題", "BACKGROUND": "#1E1E1E", ...},
        "light": {"name": "?? 淺色主題", "BACKGROUND": "#F5F5F5", ...},
        "purple": {"name": "?? 紫色主題", "BACKGROUND": "#2A0A3E", ...},
        "gradient": {"name": "?? 漸變主題", 
                    "BACKGROUND": "qlineargradient(...)", ...}
    }

支持4種預(yù)設(shè)主題,一鍵切換不重啟

動態(tài)交互效果

  • 按鈕按壓動畫(縮放效果)
  • 懸停狀態(tài)高亮提示
  • 平滑的列表滾動

智能圖標(biāo)系統(tǒng)

def set_icon(self, path):
    if os.path.isdir(path):
        self.icon_label.setText(emoji.emojize("??"))
    elif ext in ('.exe', '.bat', '.cmd'):
        self.icon_label.setText(emoji.emojize("???"))
    # 其他文件類型處理...

自動識別文件類型顯示對應(yīng)emoji圖標(biāo)

跨平臺兼容性

# Windows創(chuàng)建快捷方式
winshell.CreateShortcut(...)
# macOS創(chuàng)建替身
os.symlink(...)
# Linux創(chuàng)建.desktop文件
with open(shortcut_path, "w") as f:
    f.write(desktop_file)

效果展示

淺色主題界面

漸變主題效果

開發(fā)步驟詳解

環(huán)境準(zhǔn)備

pip install PyQt5 emoji winshell  # Windows額外安裝

項目結(jié)構(gòu)

shortcut_manager/
├── main.py              # 主程序入口
├── themes/              # 主題配置文件
├── icons/               # 圖標(biāo)資源
└── shortcuts.json       # 快捷方式存儲文件

核心實現(xiàn)流程

  • 初始化主窗口:設(shè)置基本屬性和布局
  • 加載主題系統(tǒng):讀取ThemeManager配置
  • 構(gòu)建UI組件
    • 標(biāo)題欄(帶主題切換)
    • 快捷方式列表(自定義ItemWidget)
    • 操作按鈕區(qū)域
  • 實現(xiàn)業(yè)務(wù)邏輯
    • 添加快捷方式
    • 打開/刪除條目
    • 創(chuàng)建桌面快捷方式
  • 持久化存儲:JSON格式保存配置

核心代碼解析

自定義動畫按鈕

class AnimatedButton(QPushButton):
    def mousePressEvent(self, event):
        self._animation.setEndValue(self.geometry().adjusted(2, 2, -2, -2))
        self._animation.start()

按壓時產(chǎn)生縮小效果,釋放時恢復(fù)

主題切換機制

def change_theme(self, theme_key):
    self.current_theme = theme_key
    # 動態(tài)更新所有組件樣式
    self.update_ui_style()

跨平臺快捷方式創(chuàng)建

def create_desktop_shortcut(self):
    if platform.system() == "Windows":
        # Windows使用winshell
    elif platform.system() == "Darwin":
        # macOS使用符號鏈接
    else:
        # Linux使用.desktop文件

列表項自定義Widget

class ShortcutItemWidget(QWidget):
    def __init__(self, name, path, theme):
        super().__init__()
        # 構(gòu)建包含圖標(biāo)、名稱、路徑的自定義布局

源碼下載

import sys
import os
import json
import platform
import emoji
import subprocess
from PyQt5.QtWidgets import (QApplication, QMainWindow, QWidget, QVBoxLayout, QHBoxLayout, 
                            QLabel, QLineEdit, QPushButton, QListWidget, QListWidgetItem,
                            QFrame, QScrollArea, QFileDialog, QMessageBox, QMenu, QAction,
                            QSizePolicy, QSpacerItem, QStatusBar)
from PyQt5.QtCore import Qt, QSize, QPoint, QPropertyAnimation, QEasingCurve, QTimer
from PyQt5.QtGui import (QColor, QLinearGradient, QPainter, QFont, QFontDatabase, QPalette, 
                        QIcon, QPixmap, QMovie)

class EmojiLabel(QLabel):
    """支持emoji的標(biāo)簽"""
    def __init__(self, text="", parent=None):
        super().__init__(parent)
        self.setText(emoji.emojize(text))
        
class ThemeManager:
    """管理不同的UI主題"""
    THEMES = {
        "dark": {
            "name": "?? 深色主題",
            "BACKGROUND": "#1E1E1E",
            "FOREGROUND": "#FFFFFF",
            "PRIMARY": "#6A5ACD",  # 紫羅蘭色
            "SECONDARY": "#303030",
            "TERTIARY": "#404040",
            "HIGHLIGHT": "#9370DB",  # 中等紫羅蘭色
            "ERROR": "#FF5252",
            "SUCCESS": "#4CAF50",
            "WARNING": "#FFA500",
            "TITLE_FONT": ("Segoe UI", 14, QFont.Bold),
            "HEADING_FONT": ("Segoe UI", 12, QFont.Bold),
            "NORMAL_FONT": ("Segoe UI", 10, QFont.Normal),
            "SMALL_FONT": ("Segoe UI", 9, QFont.Normal),
            "BUTTON_RADIUS": "12px",
            "CARD_RADIUS": "15px",
            "SHADOW": "0 4px 8px rgba(0, 0, 0, 0.3)"
        },
        "light": {
            "name": "?? 淺色主題",
            "BACKGROUND": "#F5F5F5",
            "FOREGROUND": "#000000",
            "PRIMARY": "#4169E1",  # 皇家藍(lán)
            "SECONDARY": "#E0E0E0",
            "TERTIARY": "#BDBDBD",
            "HIGHLIGHT": "#6495ED",  # 矢車菊藍(lán)
            "ERROR": "#D32F2F",
            "SUCCESS": "#388E3C",
            "WARNING": "#F57C00",
            "TITLE_FONT": ("Segoe UI", 14, QFont.Bold),
            "HEADING_FONT": ("Segoe UI", 12, QFont.Bold),
            "NORMAL_FONT": ("Segoe UI", 10, QFont.Normal),
            "SMALL_FONT": ("Segoe UI", 9, QFont.Normal),
            "BUTTON_RADIUS": "12px",
            "CARD_RADIUS": "15px",
            "SHADOW": "0 4px 8px rgba(0, 0, 0, 0.1)"
        },
        "purple": {
            "name": "?? 紫色主題",
            "BACKGROUND": "#2A0A3E",
            "FOREGROUND": "#FFFFFF",
            "PRIMARY": "#9C27B0",
            "SECONDARY": "#4A148C",
            "TERTIARY": "#7B1FA2",
            "HIGHLIGHT": "#BA68C8",
            "ERROR": "#FF5252",
            "SUCCESS": "#4CAF50",
            "WARNING": "#FFA500",
            "TITLE_FONT": ("Segoe UI", 14, QFont.Bold),
            "HEADING_FONT": ("Segoe UI", 12, QFont.Bold),
            "NORMAL_FONT": ("Segoe UI", 10, QFont.Normal),
            "SMALL_FONT": ("Segoe UI", 9, QFont.Normal),
            "BUTTON_RADIUS": "12px",
            "CARD_RADIUS": "15px",
            "SHADOW": "0 4px 8px rgba(0, 0, 0, 0.3)"
        },
        "gradient": {
            "name": "?? 漸變主題",
            "BACKGROUND": "qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #1E1E1E, stop:1 #2A0A3E)",
            "FOREGROUND": "#FFFFFF",
            "PRIMARY": "qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #6A5ACD, stop:1 #9C27B0)",
            "SECONDARY": "rgba(48, 48, 48, 0.7)",
            "TERTIARY": "rgba(64, 64, 64, 0.7)",
            "HIGHLIGHT": "qlineargradient(x1:0, y1:0, x2:1, y2:1, stop:0 #9370DB, stop:1 #BA68C8)",
            "ERROR": "#FF5252",
            "SUCCESS": "#4CAF50",
            "WARNING": "#FFA500",
            "TITLE_FONT": ("Segoe UI", 14, QFont.Bold),
            "HEADING_FONT": ("Segoe UI", 12, QFont.Bold),
            "NORMAL_FONT": ("Segoe UI", 10, QFont.Normal),
            "SMALL_FONT": ("Segoe UI", 9, QFont.Normal),
            "BUTTON_RADIUS": "12px",
            "CARD_RADIUS": "15px",
            "SHADOW": "0 4px 8px rgba(0, 0, 0, 0.3)"
        }
    }

    @staticmethod
    def get_theme(theme_name):
        """獲取指定主題的配置"""
        return ThemeManager.THEMES.get(theme_name, ThemeManager.THEMES["dark"])

    @staticmethod
    def get_theme_names():
        """獲取所有主題的名稱"""
        return [ThemeManager.THEMES[key]["name"] for key in ThemeManager.THEMES]

    @staticmethod
    def get_theme_keys():
        """獲取所有主題的鍵"""
        return list(ThemeManager.THEMES.keys())

class AnimatedButton(QPushButton):
    """帶有動畫效果的按鈕"""
    def __init__(self, text="", parent=None):
        super().__init__(text, parent)
        self.setCursor(Qt.PointingHandCursor)
        self._animation = QPropertyAnimation(self, b"geometry")
        self._animation.setDuration(200)
        self._animation.setEasingCurve(QEasingCurve.OutQuad)
        
    def mousePressEvent(self, event):
        self._animation.stop()
        self._animation.setStartValue(self.geometry())
        self._animation.setEndValue(self.geometry().adjusted(2, 2, -2, -2))
        self._animation.start()
        super().mousePressEvent(event)
        
    def mouseReleaseEvent(self, event):
        self._animation.stop()
        self._animation.setStartValue(self.geometry())
        self._animation.setEndValue(self.geometry().adjusted(-2, -2, 2, 2))
        self._animation.start()
        super().mouseReleaseEvent(event)

class ShortcutItemWidget(QWidget):
    """自定義快捷方式列表項"""
    def __init__(self, name, path, theme, parent=None):
        super().__init__(parent)
        self.theme = theme
        self.setup_ui(name, path)
        
    def setup_ui(self, name, path):
        layout = QHBoxLayout(self)
        layout.setContentsMargins(15, 10, 15, 10)
        layout.setSpacing(15)
        
        # 圖標(biāo)
        self.icon_label = QLabel()
        self.icon_label.setFixedSize(64, 64)
        self.set_icon(path)
        layout.addWidget(self.icon_label)
        
        # 文本信息
        text_layout = QVBoxLayout()
        text_layout.setSpacing(30)
        text_layout.setContentsMargins(5,0, 0, 0)# 調(diào)整文本邊距
        
        self.name_label = QLabel(name)
        self.name_label.setFont(QFont(self.theme["NORMAL_FONT"][0], self.theme["NORMAL_FONT"][1], self.theme["NORMAL_FONT"][2]))
        self.name_label.setStyleSheet(f"color: {self.theme['FOREGROUND']};")
        self.name_label.setWordWrap(True)  # 允許文本換行
        
        self.path_label = QLabel(path)
        self.path_label.setFont(QFont(self.theme["SMALL_FONT"][0], self.theme["SMALL_FONT"][1], self.theme["SMALL_FONT"][2]))
        self.path_label.setStyleSheet(f"color: {self.theme['TERTIARY']};")
        self.path_label.setWordWrap(True)  # 允許文本換行
        self.path_label.setMaximumWidth(400)  # 限制路徑顯示寬度
        
        text_layout.addWidget(self.name_label)
        text_layout.addWidget(self.path_label)
        layout.addLayout(text_layout, stretch=1)  # 添加拉伸因子
        
        # 添加彈性空間
        layout.addSpacerItem(QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum))
        
        # 懸停效果
        self.setAutoFillBackground(True)
        palette = self.palette()
        palette.setColor(QPalette.Background, QColor(self.theme["SECONDARY"]))
        self.setPalette(palette)
        
    def set_icon(self, path):
        """根據(jù)路徑類型設(shè)置不同圖標(biāo)"""
        if os.path.isdir(path):
            # 文件夾圖標(biāo)
            icon = QIcon.fromTheme("folder")
            if icon.isNull():
                self.icon_label.setText(emoji.emojize("??"))
                self.icon_label.setStyleSheet(f"""
                    font-size: 20px;
                    color: {self.theme['PRIMARY']};
                """)
            else:
                pixmap = icon.pixmap(32, 32)
                self.icon_label.setPixmap(pixmap)
        else:
            # 文件圖標(biāo)
            icon = QIcon.fromTheme("application-x-executable")
            if icon.isNull():
                # 根據(jù)文件擴(kuò)展名顯示不同emoji
                ext = os.path.splitext(path)[1].lower()
                if ext in ('.exe', '.bat', '.cmd'):
                    self.icon_label.setText(emoji.emojize("???"))
                elif ext in ('.py', '.sh'):
                    self.icon_label.setText(emoji.emojize("??"))
                else:
                    self.icon_label.setText(emoji.emojize("??"))
                self.icon_label.setStyleSheet(f"""
                    font-size: 20px;
                    color: {self.theme['PRIMARY']};
                """)
            else:
                # 使用系統(tǒng)文件圖標(biāo)
                icon = QIcon.fromTheme(QIcon.fromTheme("application-x-executable"))
                if os.path.exists(path):
                    icon = QIcon(path)
                pixmap = icon.pixmap(32, 32)
                self.icon_label.setPixmap(pixmap)
        
        self.icon_label.setAlignment(Qt.AlignCenter)

class DesktopShortcutManager(QMainWindow):
    def __init__(self):
        super().__init__()
        
        # 窗口設(shè)置
        self.setWindowTitle("?? 桌面快捷方式管理器")
        self.setGeometry(100, 100, 1000, 700)  # 增大窗口尺寸
        
        # 初始化數(shù)據(jù)
        self.current_theme = "dark"
        self.shortcuts = {}
        self.config_file = "shortcut_manager_config.json"
        self.shortcuts_file = "desktop_shortcuts.json"
        
        # 加載配置
        self.load_config()
        
        # 創(chuàng)建UI
        self.init_ui()
        
        # 加載快捷方式
        self.load_shortcuts()
        
    def get_current_theme(self):
        """獲取當(dāng)前主題配置"""
        return ThemeManager.get_theme(self.current_theme)
    
    def load_config(self):
        """加載配置文件"""
        if os.path.exists(self.config_file):
            try:
                with open(self.config_file, 'r', encoding='utf-8') as f:
                    config = json.load(f)
                    if "theme" in config and config["theme"] in ThemeManager.get_theme_keys():
                        self.current_theme = config["theme"]
            except Exception as e:
                print(f"加載配置失敗: {str(e)}")
    
    def save_config(self):
        """保存配置文件"""
        try:
            with open(self.config_file, 'w', encoding='utf-8') as f:
                json.dump({"theme": self.current_theme}, f)
        except Exception as e:
            print(f"保存配置失敗: {str(e)}")
    
    def init_ui(self):
        """初始化用戶界面"""
        theme = self.get_current_theme()
        
        # 設(shè)置主窗口背景
        if theme["BACKGROUND"].startswith("qlineargradient"):
            self.setStyleSheet(f"""
                QMainWindow {{
                    background: {theme['BACKGROUND']};
                }}
            """)
        else:
            palette = self.palette()
            palette.setColor(QPalette.Background, QColor(theme["BACKGROUND"]))
            self.setPalette(palette)
        
        # 創(chuàng)建中央部件
        central_widget = QWidget()
        self.setCentralWidget(central_widget)
        
        # 主布局
        main_layout = QVBoxLayout(central_widget)
        main_layout.setContentsMargins(15, 15, 15, 15)  # 調(diào)整邊距
        main_layout.setSpacing(15)
        
        # 標(biāo)題欄
        self.create_title_bar(main_layout)
        
        # 內(nèi)容區(qū)域
        content_widget = QWidget()
        content_layout = QHBoxLayout(content_widget)
        content_layout.setContentsMargins(0, 0, 0, 0)
        content_layout.setSpacing(15)
        
        # 快捷方式列表
        self.create_shortcut_list(content_layout)
        
        # 操作按鈕區(qū)域
        self.create_action_buttons(content_layout)
        
        main_layout.addWidget(content_widget)
        
        # 狀態(tài)欄
        self.create_status_bar()
        
        # 創(chuàng)建菜單(只創(chuàng)建一次)
        if not hasattr(self, 'menu_created'):
            self.create_menu()
            self.menu_created = True
    
    def create_title_bar(self, parent_layout):
        """創(chuàng)建標(biāo)題欄"""
        theme = self.get_current_theme()
        
        title_bar = QWidget()
        title_bar_layout = QHBoxLayout(title_bar)
        title_bar_layout.setContentsMargins(0, 0, 0, 0)
        
        # 標(biāo)題
        self.title_label = EmojiLabel("?? 桌面快捷方式管理器")
        self.title_label.setFont(QFont(theme["TITLE_FONT"][0], theme["TITLE_FONT"][1], theme["TITLE_FONT"][2]))
        self.title_label.setStyleSheet(f"color: {theme['PRIMARY']};")
        
        # 主題選擇器
        self.theme_selector = QPushButton(emoji.emojize(theme["name"] + " ▼"))
        self.theme_selector.setFont(QFont(theme["NORMAL_FONT"][0], theme["NORMAL_FONT"][1], theme["NORMAL_FONT"][2]))
        self.theme_selector.setStyleSheet(f"""
            QPushButton {{
                background-color: {theme['SECONDARY']};
                color: {theme['FOREGROUND']};
                border-radius: {theme['BUTTON_RADIUS']};
                padding: 8px 12px;
                border: none;
            }}
            QPushButton:hover {{
                background-color: {theme['TERTIARY']};
            }}
        """)
        
        # 創(chuàng)建主題菜單
        self.theme_menu = QMenu(self)
        for theme_key in ThemeManager.get_theme_keys():
            theme_data = ThemeManager.get_theme(theme_key)
            action = QAction(emoji.emojize(theme_data["name"]), self)
            action.triggered.connect(lambda _, key=theme_key: self.change_theme(key))
            self.theme_menu.addAction(action)
        
        self.theme_selector.setMenu(self.theme_menu)
        
        # 添加彈性空間
        spacer = QSpacerItem(0, 0, QSizePolicy.Expanding, QSizePolicy.Minimum)
        
        title_bar_layout.addWidget(self.title_label)
        title_bar_layout.addSpacerItem(spacer)
        title_bar_layout.addWidget(self.theme_selector)
        
        parent_layout.addWidget(title_bar)
    
    def create_shortcut_list(self, parent_layout):
        """創(chuàng)建快捷方式列表"""
        theme = self.get_current_theme()
        
        # 創(chuàng)建卡片容器
        self.list_card = QWidget()
        self.list_card.setStyleSheet(f"""
            background-color: {theme['SECONDARY']};
            border-radius: {theme['CARD_RADIUS']};
            padding: 15px;
        """)
        
        card_layout = QVBoxLayout(self.list_card)
        card_layout.setContentsMargins(0, 0, 0, 0)
        card_layout.setSpacing(15)
        
        # 標(biāo)題
        self.list_title = QLabel("?? 快捷方式列表")
        self.list_title.setFont(QFont(theme["HEADING_FONT"][0], theme["HEADING_FONT"][1], theme["HEADING_FONT"][2]))
        self.list_title.setStyleSheet(f"color: {theme['FOREGROUND']};")
        card_layout.addWidget(self.list_title)
        
        # 列表部件
        self.shortcut_list = QListWidget()
        self.shortcut_list.setStyleSheet(f"""
            QListWidget {{
                background-color: transparent;
                border: none;
                outline: none;
            }}
            QListWidget::item {{
                border-bottom: 1px solid {theme['TERTIARY']};
            }}
            QListWidget::item:selected {{
                background-color: {theme['PRIMARY']};
                border-radius: 5px;
            }}
        """)
        self.shortcut_list.setVerticalScrollMode(QListWidget.ScrollPerPixel)
        self.shortcut_list.setHorizontalScrollMode(QListWidget.ScrollPerPixel)
        
        # 添加到卡片
        card_layout.addWidget(self.shortcut_list)
        
        # 添加到主布局
        parent_layout.addWidget(self.list_card, stretch=3)
    
    def create_action_buttons(self, parent_layout):
        """創(chuàng)建操作按鈕區(qū)域"""
        theme = self.get_current_theme()
        
        # 創(chuàng)建卡片容器
        self.action_card = QWidget()
        self.action_card.setStyleSheet(f"""
            background-color: {theme['SECONDARY']};
            border-radius: {theme['CARD_RADIUS']};
            padding: 15px;
        """)
        
        card_layout = QVBoxLayout(self.action_card)
        card_layout.setContentsMargins(0, 0, 0, 0)
        card_layout.setSpacing(15)
        
        # 標(biāo)題
        self.actions_title = QLabel("? 快捷操作")
        self.actions_title.setFont(QFont(theme["HEADING_FONT"][0], theme["HEADING_FONT"][1], theme["HEADING_FONT"][2]))
        self.actions_title.setStyleSheet(f"color: {theme['FOREGROUND']};")
        card_layout.addWidget(self.actions_title)
        
        # 添加按鈕
        self.add_btn = AnimatedButton(emoji.emojize("? 添加快捷方式"))
        self.add_btn.setStyleSheet(self.get_button_style())
        self.add_btn.clicked.connect(self.add_shortcut)
        
        # 打開按鈕
        self.open_btn = AnimatedButton(emoji.emojize("?? 打開快捷方式"))
        self.open_btn.setStyleSheet(self.get_button_style())
        self.open_btn.clicked.connect(self.open_selected_shortcut)
        
        # 刪除按鈕
        self.delete_btn = AnimatedButton(emoji.emojize("??? 刪除快捷方式"))
        self.delete_btn.setStyleSheet(self.get_button_style(True))
        self.delete_btn.clicked.connect(self.delete_shortcut)
        
        # 創(chuàng)建到桌面按鈕
        self.create_btn = AnimatedButton(emoji.emojize("??? 創(chuàng)建到桌面"))
        self.create_btn.setStyleSheet(self.get_button_style())
        self.create_btn.clicked.connect(self.create_desktop_shortcut)
        
        # 添加到布局
        card_layout.addWidget(self.add_btn)
        card_layout.addWidget(self.open_btn)
        card_layout.addWidget(self.delete_btn)
        card_layout.addWidget(self.create_btn)
        
        # 添加彈性空間
        card_layout.addSpacerItem(QSpacerItem(0, 0, QSizePolicy.Minimum, QSizePolicy.Expanding))
        
        # 添加到主布局
        parent_layout.addWidget(self.action_card, stretch=1)
    
    def get_button_style(self, is_destructive=False):
        """獲取按鈕樣式"""
        theme = self.get_current_theme()
        color = theme["ERROR"] if is_destructive else theme["PRIMARY"]
        
        return f"""
            QPushButton {{
                background-color: {color};
                color: {theme['FOREGROUND']};
                border-radius: {theme['BUTTON_RADIUS']};
                padding: 12px;
                font-weight: bold;
                border: none;
            }}
            QPushButton:hover {{
                background-color: {theme['HIGHLIGHT']};
            }}
            QPushButton:pressed {{
                background-color: {theme['PRIMARY']};
            }}
        """
    
    def create_status_bar(self):
        """創(chuàng)建狀態(tài)欄"""
        theme = self.get_current_theme()
        
        self.status_bar = QStatusBar()
        self.setStatusBar(self.status_bar)
        
        # 狀態(tài)消息
        self.status_message = QLabel("?? 就緒")
        self.status_message.setFont(QFont(theme["SMALL_FONT"][0], theme["SMALL_FONT"][1], theme["SMALL_FONT"][2]))
        self.status_message.setStyleSheet(f"color: {theme['FOREGROUND']};")
        
        self.status_bar.addWidget(self.status_message, stretch=1)
    
    def create_menu(self):
        """創(chuàng)建菜單欄(只創(chuàng)建一次)"""
        menubar = self.menuBar()
        theme = self.get_current_theme()
        
        # 設(shè)置菜單欄樣式
        menubar.setStyleSheet(f"""
            QMenuBar {{
                background-color: {theme['SECONDARY']};
                color: {theme['FOREGROUND']};
                padding: 5px;
                border-bottom: 1px solid {theme['TERTIARY']};
            }}
            QMenuBar::item {{
                padding: 5px 10px;
                background-color: transparent;
            }}
            QMenuBar::item:selected {{
                background-color: {theme['PRIMARY']};
                border-radius: 5px;
            }}
            QMenu {{
                background-color: {theme['SECONDARY']};
                color: {theme['FOREGROUND']};
                border: 1px solid {theme['TERTIARY']};
            }}
            QMenu::item:selected {{
                background-color: {theme['PRIMARY']};
            }}
        """)
        
        # 文件菜單
        file_menu = menubar.addMenu("?? 文件")
        
        save_action = QAction("?? 保存所有快捷方式", self)
        save_action.triggered.connect(self.save_shortcuts)
        file_menu.addAction(save_action)
        
        file_menu.addSeparator()
        
        exit_action = QAction("?? 退出", self)
        exit_action.triggered.connect(self.close)
        file_menu.addAction(exit_action)
        
        # 幫助菜單
        help_menu = menubar.addMenu("? 幫助")
        
        about_action = QAction("?? 關(guān)于", self)
        about_action.triggered.connect(self.show_about)
        help_menu.addAction(about_action)
    
    def change_theme(self, theme_key):
        """更改UI主題"""
        if theme_key not in ThemeManager.get_theme_keys():
            return
        
        self.current_theme = theme_key
        self.save_config()
        
        # 更新UI樣式而不重新創(chuàng)建整個UI
        theme = self.get_current_theme()
        
        # 更新主窗口背景
        if theme["BACKGROUND"].startswith("qlineargradient"):
            self.setStyleSheet(f"""
                QMainWindow {{
                    background: {theme['BACKGROUND']};
                }}
            """)
        else:
            palette = self.palette()
            palette.setColor(QPalette.Background, QColor(theme["BACKGROUND"]))
            self.setPalette(palette)
        
        # 更新標(biāo)題欄
        self.title_label.setFont(QFont(theme["TITLE_FONT"][0], theme["TITLE_FONT"][1], theme["TITLE_FONT"][2]))
        self.title_label.setStyleSheet(f"color: {theme['PRIMARY']};")
        
        # 更新主題選擇器
        self.theme_selector.setText(emoji.emojize(theme["name"] + " ▼"))
        self.theme_selector.setFont(QFont(theme["NORMAL_FONT"][0], theme["NORMAL_FONT"][1], theme["NORMAL_FONT"][2]))
        self.theme_selector.setStyleSheet(f"""
            QPushButton {{
                background-color: {theme['SECONDARY']};
                color: {theme['FOREGROUND']};
                border-radius: {theme['BUTTON_RADIUS']};
                padding: 8px 12px;
                border: none;
            }}
            QPushButton:hover {{
                background-color: {theme['TERTIARY']};
            }}
        """)
        
        # 更新快捷方式列表卡片
        self.list_card.setStyleSheet(f"""
            background-color: {theme['SECONDARY']};
            border-radius: {theme['CARD_RADIUS']};
            padding: 15px;
        """)
        self.list_title.setFont(QFont(theme["HEADING_FONT"][0], theme["HEADING_FONT"][1], theme["HEADING_FONT"][2]))
        self.list_title.setStyleSheet(f"color: {theme['FOREGROUND']};")
        self.shortcut_list.setStyleSheet(f"""
            QListWidget {{
                background-color: transparent;
                border: none;
                outline: none;
            }}
            QListWidget::item {{
                border-bottom: 1px solid {theme['TERTIARY']};
            }}
            QListWidget::item:selected {{
                background-color: {theme['PRIMARY']};
                border-radius: 5px;
            }}
        """)
        
        # 更新操作按鈕卡片
        self.action_card.setStyleSheet(f"""
            background-color: {theme['SECONDARY']};
            border-radius: {theme['CARD_RADIUS']};
            padding: 15px;
        """)
        self.actions_title.setFont(QFont(theme["HEADING_FONT"][0], theme["HEADING_FONT"][1], theme["HEADING_FONT"][2]))
        self.actions_title.setStyleSheet(f"color: {theme['FOREGROUND']};")
        
        # 更新按鈕樣式
        self.add_btn.setStyleSheet(self.get_button_style())
        self.open_btn.setStyleSheet(self.get_button_style())
        self.delete_btn.setStyleSheet(self.get_button_style(True))
        self.create_btn.setStyleSheet(self.get_button_style())
        
        # 更新狀態(tài)欄
        self.status_message.setFont(QFont(theme["SMALL_FONT"][0], theme["SMALL_FONT"][1], theme["SMALL_FONT"][2]))
        self.status_message.setStyleSheet(f"color: {theme['FOREGROUND']};")
        
        # 更新菜單欄樣式
        menubar = self.menuBar()
        menubar.setStyleSheet(f"""
            QMenuBar {{
                background-color: {theme['SECONDARY']};
                color: {theme['FOREGROUND']};
                padding: 5px;
                border-bottom: 1px solid {theme['TERTIARY']};
            }}
            QMenuBar::item {{
                padding: 5px 10px;
                background-color: transparent;
            }}
            QMenuBar::item:selected {{
                background-color: {theme['PRIMARY']};
                border-radius: 5px;
            }}
            QMenu {{
                background-color: {theme['SECONDARY']};
                color: {theme['FOREGROUND']};
                border: 1px solid {theme['TERTIARY']};
            }}
            QMenu::item:selected {{
                background-color: {theme['PRIMARY']};
            }}
        """)
        
        # 刷新快捷方式列表項樣式
        self.refresh_shortcut_list()
        
        # 顯示主題更改成功消息
        theme_name = ThemeManager.get_theme(theme_key)["name"]
        self.show_status_message(f"已切換到 {theme_name}", "success")
    
    def show_status_message(self, message, type="info"):
        """顯示狀態(tài)欄消息"""
        theme = self.get_current_theme()
        
        if type == "info":
            icon = "??"
            color = theme["PRIMARY"]
        elif type == "success":
            icon = "??"
            color = theme["SUCCESS"]
        elif type == "error":
            icon = "??"
            color = theme["ERROR"]
        elif type == "warning":
            icon = "??"
            color = theme["WARNING"]
        else:
            icon = "??"
            color = theme["PRIMARY"]
        
        self.status_message.setText(f"{icon} {message}")
        self.status_message.setStyleSheet(f"color: {color};")
        
        # 3秒后自動清除消息
        QTimer.singleShot(3000, lambda: self.status_message.setText("?? 就緒"))
    
    def load_shortcuts(self):
        """從文件加載已保存的快捷方式"""
        if os.path.exists(self.shortcuts_file):
            try:
                with open(self.shortcuts_file, 'r', encoding='utf-8') as f:
                    self.shortcuts = json.load(f)
                self.refresh_shortcut_list()
                self.show_status_message(f"已加載 {len(self.shortcuts)} 個快捷方式", "success")
            except Exception as e:
                self.show_status_message(f"加載快捷方式失敗: {str(e)}", "error")
                self.shortcuts = {}
        else:
            self.shortcuts = {}
            self.show_status_message("沒有找到快捷方式文件,已創(chuàng)建新列表", "info")
    
    def save_shortcuts(self):
        """保存快捷方式到文件"""
        try:
            with open(self.shortcuts_file, 'w', encoding='utf-8') as f:
                json.dump(self.shortcuts, f, ensure_ascii=False, indent=4)
            self.show_status_message("快捷方式保存成功", "success")
            return True
        except Exception as e:
            self.show_status_message(f"保存快捷方式失敗: {str(e)}", "error")
            return False
    
    def refresh_shortcut_list(self):
        """刷新快捷方式列表"""
        self.shortcut_list.clear()
        
        for name, path in self.shortcuts.items():
            item = QListWidgetItem()
            item.setSizeHint(QSize(0, 80))  # 增加項高度以適應(yīng)多行文本
            
            widget = ShortcutItemWidget(name, path, self.get_current_theme())
            
            self.shortcut_list.addItem(item)
            self.shortcut_list.setItemWidget(item, widget)
    
    def add_shortcut(self):
        """添加新的快捷方式(支持文件和文件夾)"""
        path, _ = QFileDialog.getOpenFileName(
            self, 
            "選擇文件或文件夾", 
            "", 
            "所有文件 (*);;可執(zhí)行文件 (*.exe *.bat *.cmd);;腳本文件 (*.py *.sh);;文件夾"
        )
        
        if not path:
            return
        
        # 獲取名稱
        name = os.path.basename(path)
        
        # 如果已存在同名快捷方式,添加數(shù)字后綴
        base_name = os.path.splitext(name)[0]
        ext = os.path.splitext(name)[1]
        counter = 1
        while name in self.shortcuts:
            name = f"{base_name} ({counter}){ext}"
            counter += 1
        
        # 添加到快捷方式字典
        self.shortcuts[name] = path
        
        # 保存并刷新列表
        if self.save_shortcuts():
            self.refresh_shortcut_list()
            self.show_status_message(f"已添加快捷方式: {name}", "success")
    
    def get_selected_shortcut(self):
        """獲取選中的快捷方式"""
        selected_items = self.shortcut_list.selectedItems()
        if not selected_items:
            return None, None
        
        item = selected_items[0]
        widget = self.shortcut_list.itemWidget(item)
        return widget.name_label.text(), widget.path_label.text()
    
    def open_selected_shortcut(self):
        """打開選中的快捷方式"""
        name, path = self.get_selected_shortcut()
        if not name:
            self.show_status_message("請先選擇一個快捷方式", "warning")
            return
        
        if not os.path.exists(path):
            self.show_status_message(f"路徑不存在: {path}", "error")
            return
        
        try:
            if platform.system() == "Windows":
                if os.path.isdir(path):
                    os.startfile(path)
                else:
                    os.startfile(path)
            elif platform.system() == "Darwin":
                if os.path.isdir(path):
                    subprocess.run(["open", path])
                else:
                    subprocess.run(["open", path])
            else:
                if os.path.isdir(path):
                    subprocess.run(["xdg-open", path])
                else:
                    subprocess.run(["xdg-open", path])
            
            self.show_status_message(f"已打開: {name}", "success")
        except Exception as e:
            self.show_status_message(f"打開失敗: {str(e)}", "error")
    
    def delete_shortcut(self):
        """刪除選中的快捷方式"""
        name, path = self.get_selected_shortcut()
        if not name:
            self.show_status_message("請先選擇一個快捷方式", "warning")
            return
        
        # 確認(rèn)對話框
        reply = QMessageBox.question(
            self, "確認(rèn)刪除",
            f"確定要刪除快捷方式 '{name}' 嗎?",
            QMessageBox.Yes | QMessageBox.No,
            QMessageBox.No
        )
        
        if reply == QMessageBox.Yes:
            del self.shortcuts[name]
            if self.save_shortcuts():
                self.refresh_shortcut_list()
                self.show_status_message(f"已刪除快捷方式: {name}", "success")
    
    def create_desktop_shortcut(self):
        """創(chuàng)建選中的快捷方式到桌面"""
        name, path = self.get_selected_shortcut()
        if not name:
            self.show_status_message("請先選擇一個快捷方式", "warning")
            return
        
        if not os.path.exists(path):
            self.show_status_message(f"路徑不存在: {path}", "error")
            return
        
        desktop_path = os.path.join(os.path.expanduser("~"), "Desktop")
        
        try:
            if platform.system() == "Windows":
                try:
                    import winshell
                    shortcut_path = os.path.join(desktop_path, f"{name}.lnk")
                    winshell.CreateShortcut(
                        Path=shortcut_path,
                        Target=path,
                        Description=f"快捷方式到 {name}",
                        Icon=(path, 0)
                    )
                except ImportError:
                    self.show_status_message("需要安裝winshell庫: pip install winshell", "error")
                    return
            elif platform.system() == "Darwin":
                # macOS 創(chuàng)建替身
                shortcut_path = os.path.join(desktop_path, name)
                os.symlink(path, shortcut_path)
            else:
                # Linux 創(chuàng)建.desktop文件
                shortcut_path = os.path.join(desktop_path, f"{name}.desktop")
                icon_path = path if os.path.isfile(path) else "system-file-manager"
                desktop_file = f"""[Desktop Entry]
Version=1.0
Type=Application
Name={name}
Exec={path}
Icon={icon_path}
Terminal=false
"""
                with open(shortcut_path, "w") as f:
                    f.write(desktop_file)
                os.chmod(shortcut_path, 0o755)
            
            self.show_status_message(f"已在桌面創(chuàng)建快捷方式: {name}", "success")
        except Exception as e:
            self.show_status_message(f"創(chuàng)建快捷方式失敗: {str(e)}", "error")
    
    def show_about(self):
        """顯示關(guān)于對話框"""
        theme = self.get_current_theme()
        
        about_box = QMessageBox(self)
        about_box.setWindowTitle("?? 關(guān)于")
        about_box.setText("""
            <h2>?? 桌面快捷方式管理器</h2>
            <p>版本 2.0</p>
            <p>一個美觀實用的快捷方式管理工具</p>
            <p>使用 PyQt5 和 emoji 構(gòu)建</p>
            <p>? 2025 版權(quán)所有 創(chuàng)客白澤</p>
        """)
        
        # 設(shè)置樣式
        about_box.setStyleSheet(f"""
            QMessageBox {{
                background-color: {theme['SECONDARY']};
                color: {theme['FOREGROUND']};
            }}
            QLabel {{
                color: {theme['FOREGROUND']};
            }}
            QPushButton {{
                background-color: {theme['PRIMARY']};
                color: {theme['FOREGROUND']};
                border-radius: {theme['BUTTON_RADIUS']};
                padding: 8px;
                min-width: 80px;
            }}
            QPushButton:hover {{
                background-color: {theme['HIGHLIGHT']};
            }}
        """)
        
        about_box.exec_()

if __name__ == "__main__":
    app = QApplication(sys.argv)
    
    # 設(shè)置應(yīng)用程序圖標(biāo)
    if platform.system() == "Windows":
        import ctypes
        myappid = "desktop.shortcut.manager.2.0"
        ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID(myappid)
    
    # 創(chuàng)建并顯示主窗口
    window = DesktopShortcutManager()
    window.show()
    
    sys.exit(app.exec_())

總結(jié)

本項目通過PyQt5實現(xiàn)了:

  • 現(xiàn)代化UI設(shè)計:卡片布局+動畫+多主題
  • 完整功能閉環(huán):增刪改查快捷方式
  • 跨平臺兼容:適配三大操作系統(tǒng)
  • 用戶體驗優(yōu)化:狀態(tài)提示、emoji圖標(biāo)

擴(kuò)展建議

  • 增加云同步功能
  • 支持快捷鍵操作
  • 添加分類標(biāo)簽系統(tǒng)

到此這篇關(guān)于Python+PyQt5打造炫酷的桌面快捷方式管理器的文章就介紹到這了,更多相關(guān)Python快捷方式管理器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python進(jìn)程的通信Queue、Pipe實例分析

    Python進(jìn)程的通信Queue、Pipe實例分析

    這篇文章主要介紹了Python進(jìn)程的通信Queue、Pipe,結(jié)合實例形式分析了Python進(jìn)程通信Queue、Pipe基本概念、用法及操作注意事項,需要的朋友可以參考下
    2020-03-03
  • Python中利用aiohttp制作異步爬蟲及簡單應(yīng)用

    Python中利用aiohttp制作異步爬蟲及簡單應(yīng)用

    asyncio可以實現(xiàn)單線程并發(fā)IO操作,是Python中常用的異步處理模塊。這篇文章主要介紹了Python中利用aiohttp制作異步爬蟲的相關(guān)知識,需要的朋友可以參考下
    2018-11-11
  • python技巧分享Excel創(chuàng)建和修改

    python技巧分享Excel創(chuàng)建和修改

    這篇文章主要介紹了python技巧分享Excel創(chuàng)建和修改,openpyxl是一個讀寫Excel文檔的Python庫,能夠同時讀取和修改Excel文檔。下面來看下文詳細(xì)介紹,需要的小伙伴可以參考一下
    2022-02-02
  • Python里字典的基本用法(包括嵌套字典)

    Python里字典的基本用法(包括嵌套字典)

    今天小編就為大家分享一篇關(guān)于Python里字典的基本用法(包括嵌套字典),小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-02-02
  • python在linux系統(tǒng)下獲取系統(tǒng)內(nèi)存使用情況的方法

    python在linux系統(tǒng)下獲取系統(tǒng)內(nèi)存使用情況的方法

    這篇文章主要介紹了python在linux系統(tǒng)下獲取系統(tǒng)內(nèi)存使用情況的方法,涉及Python在Linux平臺下獲取系統(tǒng)硬件信息的相關(guān)技巧,需要的朋友可以參考下
    2015-05-05
  • Python Pandas 對列/行進(jìn)行選擇,增加,刪除操作

    Python Pandas 對列/行進(jìn)行選擇,增加,刪除操作

    這篇文章主要介紹了Python Pandas 對列/行進(jìn)行選擇,增加,刪除操作,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • 基于Python繪制三種不同的中國結(jié)

    基于Python繪制三種不同的中國結(jié)

    馬上就要迎來新年了,就繪制了幾個中國結(jié),嘿嘿!本文為大家整理了三個繪制中國結(jié)的方法,文中的示例代碼講解詳細(xì),快跟隨小編一起動手嘗試一下吧
    2023-01-01
  • Python之format格式化函數(shù)使用及說明

    Python之format格式化函數(shù)使用及說明

    Python?2.6引入的str.format()函數(shù)增強了字符串格式化功能,支持通過{}和:語法,可以接受不限個參數(shù),位置不按順序,也可以設(shè)置參數(shù),format函數(shù)還可以接受對象和格式化數(shù)字,提供了多種方法
    2025-11-11
  • 給Python初學(xué)者的一些編程技巧

    給Python初學(xué)者的一些編程技巧

    這篇文章主要介紹了給Python初學(xué)者的一些編程技巧,皆是基于基礎(chǔ)的一些編程習(xí)慣建議,需要的朋友可以參考下
    2015-04-04
  • PyTorch?Autograd的核心原理和功能深入探究

    PyTorch?Autograd的核心原理和功能深入探究

    本文深入探討了PyTorch中Autograd的核心原理和功能,從基本概念、Tensor與Autograd的交互,到計算圖的構(gòu)建和管理,再到反向傳播和梯度計算的細(xì)節(jié),最后涵蓋了Autograd的高級特性
    2024-01-01

最新評論

馆陶县| 秭归县| 冀州市| 苏尼特左旗| 固阳县| 安吉县| 定襄县| 桂林市| 温州市| 射阳县| 吴忠市| 石狮市| 荆州市| 普安县| 方城县| 兴宁市| 盐津县| 大石桥市| 遵义市| 利辛县| 临城县| 昭平县| 雷山县| 屏南县| 山东省| 安西县| 井陉县| 安阳市| 牙克石市| 祥云县| 安图县| 康定县| 娱乐| 西畴县| 得荣县| 且末县| 大化| 新乡县| 门源| 临桂县| 株洲市|