diff --git a/__pycache__/shortcut_target.cpython-313.pyc b/__pycache__/shortcut_target.cpython-313.pyc
index fef1a15..7247c10 100644
Binary files a/__pycache__/shortcut_target.cpython-313.pyc and b/__pycache__/shortcut_target.cpython-313.pyc differ
diff --git a/db/__pycache__/__init__.cpython-313.pyc b/db/__pycache__/__init__.cpython-313.pyc
index 8433c2e..4472d17 100644
Binary files a/db/__pycache__/__init__.cpython-313.pyc and b/db/__pycache__/__init__.cpython-313.pyc differ
diff --git a/db/__pycache__/database.cpython-313.pyc b/db/__pycache__/database.cpython-313.pyc
index 3b1efd2..fac6f33 100644
Binary files a/db/__pycache__/database.cpython-313.pyc and b/db/__pycache__/database.cpython-313.pyc differ
diff --git a/main.py b/main.py
index 4082c38..e865a7a 100644
--- a/main.py
+++ b/main.py
@@ -111,6 +111,17 @@ def main():
ball.clicked.connect(lambda: panel.show_near(ball.pos(), BALL_SIZE))
ball.right_clicked.connect(lambda pos: panel.tray.contextMenu().exec(pos))
+ # 全局快捷键 Alt+` 唤醒/隐藏主界面
+ from PyQt6.QtGui import QShortcut, QKeySequence
+ _shortcut = QShortcut(QKeySequence("Alt+`"), panel)
+ _shortcut.setContext(Qt.ShortcutContext.ApplicationShortcut)
+ def _toggle_panel():
+ if panel.isVisible():
+ panel.minimize_to_ball()
+ else:
+ panel.show_near(ball.pos(), BALL_SIZE)
+ _shortcut.activated.connect(_toggle_panel)
+
has_saved = bool(database.get_setting("panel_x", ""))
if has_saved:
panel.setWindowOpacity(0)
diff --git a/softwares/InnoSetup_92412/InnoSetup-6.7.1_zh_setup.exe b/softwares/InnoSetup_92412/InnoSetup-6.7.1_zh_setup.exe
new file mode 100644
index 0000000..901ca00
Binary files /dev/null and b/softwares/InnoSetup_92412/InnoSetup-6.7.1_zh_setup.exe differ
diff --git a/ui/__pycache__/__init__.cpython-313.pyc b/ui/__pycache__/__init__.cpython-313.pyc
index b5fd8a8..5feefff 100644
Binary files a/ui/__pycache__/__init__.cpython-313.pyc and b/ui/__pycache__/__init__.cpython-313.pyc differ
diff --git a/ui/__pycache__/ball.cpython-313.pyc b/ui/__pycache__/ball.cpython-313.pyc
index da4eca8..2d4a476 100644
Binary files a/ui/__pycache__/ball.cpython-313.pyc and b/ui/__pycache__/ball.cpython-313.pyc differ
diff --git a/ui/__pycache__/dialog_style.cpython-313.pyc b/ui/__pycache__/dialog_style.cpython-313.pyc
index b8d10bd..0167c4a 100644
Binary files a/ui/__pycache__/dialog_style.cpython-313.pyc and b/ui/__pycache__/dialog_style.cpython-313.pyc differ
diff --git a/ui/__pycache__/dock.cpython-313.pyc b/ui/__pycache__/dock.cpython-313.pyc
index 372abeb..2a4ba7f 100644
Binary files a/ui/__pycache__/dock.cpython-313.pyc and b/ui/__pycache__/dock.cpython-313.pyc differ
diff --git a/ui/__pycache__/flow_layout.cpython-313.pyc b/ui/__pycache__/flow_layout.cpython-313.pyc
index 40bbfa3..ac9a412 100644
Binary files a/ui/__pycache__/flow_layout.cpython-313.pyc and b/ui/__pycache__/flow_layout.cpython-313.pyc differ
diff --git a/ui/__pycache__/group.cpython-313.pyc b/ui/__pycache__/group.cpython-313.pyc
index 1908be3..f25aa4f 100644
Binary files a/ui/__pycache__/group.cpython-313.pyc and b/ui/__pycache__/group.cpython-313.pyc differ
diff --git a/ui/__pycache__/item.cpython-313.pyc b/ui/__pycache__/item.cpython-313.pyc
index 3b2955f..1a6b05b 100644
Binary files a/ui/__pycache__/item.cpython-313.pyc and b/ui/__pycache__/item.cpython-313.pyc differ
diff --git a/ui/__pycache__/settings_window.cpython-313.pyc b/ui/__pycache__/settings_window.cpython-313.pyc
index 11558ac..38249a9 100644
Binary files a/ui/__pycache__/settings_window.cpython-313.pyc and b/ui/__pycache__/settings_window.cpython-313.pyc differ
diff --git a/ui/__pycache__/theme.cpython-313.pyc b/ui/__pycache__/theme.cpython-313.pyc
index ddf896c..f0854c6 100644
Binary files a/ui/__pycache__/theme.cpython-313.pyc and b/ui/__pycache__/theme.cpython-313.pyc differ
diff --git a/ui/dock.py b/ui/dock.py
index a26ebb0..52ae88e 100644
--- a/ui/dock.py
+++ b/ui/dock.py
@@ -22,6 +22,7 @@ from PyQt6.QtWidgets import (
QLabel,
QMessageBox,
QGridLayout,
+ QFrame,
)
from PyQt6.QtCore import (
Qt,
@@ -41,6 +42,61 @@ import ui.dialog_style as dialog_style
from ui.updater import Updater
from app_info import app_title
+
+class _ThemedTooltip(QFrame):
+ """跟随主题颜色的自定义 tooltip,替代系统黑色气泡。"""
+ def __init__(self, text: str):
+ super().__init__(None, Qt.WindowType.ToolTip | Qt.WindowType.FramelessWindowHint)
+ self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
+ self.setAttribute(Qt.WidgetAttribute.WA_ShowWithoutActivating)
+ self._lbl = QLabel(text, self)
+ self._lbl.setObjectName("tip_label")
+ lay = QVBoxLayout(self)
+ lay.setContentsMargins(0, 0, 0, 0)
+ lay.addWidget(self._lbl)
+
+ def refresh_style(self):
+ t = theme.current()
+ is_dark = theme.name() == "dark"
+ bg = "#2d2d2d" if is_dark else "#ffffff"
+ fg = "#eeeeee" if is_dark else "#111111"
+ bd = t.get("search_border", "#888")
+ self._lbl.setStyleSheet(
+ f"QLabel#tip_label {{"
+ f"background:{bg}; color:{fg}; border:1px solid {bd};"
+ f"border-radius:6px; padding:5px 9px; font-size:12px;}}"
+ )
+
+
+def _install_themed_tooltip(btn: QPushButton, text: str):
+ """给按钮安装自定义 tooltip,完全替换系统气泡。"""
+ btn.setToolTip("")
+ tip = _ThemedTooltip(text)
+ timer = QTimer()
+ timer.setSingleShot(True)
+
+ def _show():
+ tip.refresh_style()
+ tip.adjustSize()
+ pos = QCursor.pos()
+ tip.move(pos.x() + 14, pos.y() + 22)
+ tip.show()
+ tip.raise_()
+
+ def _enter(_e):
+ timer.start(400)
+
+ def _leave(_e):
+ timer.stop()
+ tip.hide()
+
+ timer.timeout.connect(_show)
+ btn.enterEvent = _enter
+ btn.leaveEvent = _leave
+ btn._tip = tip # 防 GC
+ btn._ttimer = timer # 防 GC
+
+
PANEL_W = 260
PANEL_H = 40
MIN_W, MIN_H = 400, 5
@@ -548,10 +604,9 @@ class PanelWindow(QWidget):
for tooltip, icon_name, callback in self._get_quick_actions():
btn = QPushButton()
btn.setFixedSize(34, 34)
- btn.setToolTip(tooltip)
+ _install_themed_tooltip(btn, tooltip)
btn.setStyleSheet("border:none; background:transparent; border-radius:4px;")
btn.setMouseTracking(True)
- # 鼠标落在按钮上时,也要能触发边缘检测/resize
btn.installEventFilter(self)
try:
btn.setIcon(qta.icon(icon_name, color="#888"))
@@ -712,7 +767,7 @@ class PanelWindow(QWidget):
self.menu_btn = QPushButton()
self.menu_btn.setFixedSize(28, 28)
- self.menu_btn.setToolTip("菜单")
+ _install_themed_tooltip(self.menu_btn, "菜单")
self.menu_btn.setStyleSheet(
"border:none; background:transparent; border-radius:4px;"
)
@@ -720,7 +775,7 @@ class PanelWindow(QWidget):
self.theme_btn = QPushButton()
self.theme_btn.setFixedSize(28, 28)
- self.theme_btn.setToolTip("切换亮/暗主题")
+ _install_themed_tooltip(self.theme_btn, "切换亮/暗主题")
self.theme_btn.setStyleSheet(
"border:none; background:transparent; border-radius:4px;"
)
@@ -728,7 +783,7 @@ class PanelWindow(QWidget):
self.settings_btn = QPushButton()
self.settings_btn.setFixedSize(28, 28)
- self.settings_btn.setToolTip("设置")
+ _install_themed_tooltip(self.settings_btn, "设置")
self.settings_btn.setStyleSheet(
"border:none; background:transparent; border-radius:4px;"
)
@@ -736,7 +791,7 @@ class PanelWindow(QWidget):
self.quit_btn = QPushButton()
self.quit_btn.setFixedSize(28, 28)
- self.quit_btn.setToolTip("退出程序")
+ _install_themed_tooltip(self.quit_btn, "退出程序")
self.quit_btn.setStyleSheet(
"border:none; background:transparent; border-radius:4px;"
)
@@ -746,7 +801,7 @@ class PanelWindow(QWidget):
bottom_layout.addStretch()
self.update_btn = QPushButton()
self.update_btn.setFixedSize(28, 28)
- self.update_btn.setToolTip("检查更新")
+ _install_themed_tooltip(self.update_btn, "检查更新")
self.update_btn.setStyleSheet("border:none; background:transparent; border-radius:4px;")
self.update_btn.clicked.connect(lambda: self._updater.check(silent_if_latest=False))
bottom_layout.addWidget(self.update_btn)
@@ -903,15 +958,26 @@ class PanelWindow(QWidget):
def _apply_tooltip_theme(self, t: dict, is_dark: bool):
"""让所有控件 tooltip 跟随主题(含快捷栏按钮)。"""
+ from PyQt6.QtGui import QPalette, QColor
+ from PyQt6.QtWidgets import QToolTip
+
app = QApplication.instance()
if app is None:
return
- bg = "rgba(45,45,45,245)" if is_dark else "rgba(255,255,255,250)"
- fg = "#eeeeee" if is_dark else "#111111"
- bd = t.get("menu_border") or t.get("search_border") or t.get("panel_border") or "#666"
+ bg = "#2d2d2d" if is_dark else "#ffffff"
+ fg = "#eeeeee" if is_dark else "#111111"
+ bd = t.get("menu_border") or t.get("search_border") or "#666"
+
+ # 通过 palette 强制覆盖 tooltip 颜色(Windows 上 stylesheet 单独不够)
+ palette = app.palette()
+ palette.setColor(QPalette.ColorRole.ToolTipBase, QColor(bg))
+ palette.setColor(QPalette.ColorRole.ToolTipText, QColor(fg))
+ app.setPalette(palette)
+
+ # stylesheet 同步设置(双保险)
start = "/*TOOLTIP_THEME_START*/"
- end = "/*TOOLTIP_THEME_END*/"
+ end = "/*TOOLTIP_THEME_END*/"
tooltip_css = (
f"{start}\n"
"QToolTip {\n"
@@ -921,19 +987,17 @@ class PanelWindow(QWidget):
" border-radius: 6px;\n"
" padding: 6px 8px;\n"
" font-size: 12px;\n"
+ " opacity: 240;\n"
"}\n"
f"{end}\n"
)
-
ss = app.styleSheet() or ""
if start in ss and end in ss:
- pre = ss.split(start, 1)[0]
- post = ss.split(end, 1)[1]
- ss = pre + tooltip_css + post
+ pre = ss.split(start, 1)[0]
+ post = ss.split(end, 1)[1]
+ ss = pre + tooltip_css + post
else:
- if ss and not ss.endswith("\n"):
- ss += "\n"
- ss += tooltip_css
+ ss = (ss + "\n" if ss and not ss.endswith("\n") else ss) + tooltip_css
app.setStyleSheet(ss)
def _quit_application(self):
diff --git a/ui/settings_window.py b/ui/settings_window.py
index ade3156..384e3f9 100644
--- a/ui/settings_window.py
+++ b/ui/settings_window.py
@@ -54,6 +54,7 @@ class SettingsWindow(QDialog):
("fa5s.rocket", "启动"),
("fa5s.folder-open", "缓存"),
("fa5s.heart", "捐赠"),
+ ("fa5s.info-circle", "关于"),
("fa5s.eraser", "初始化"),
]
self._nav_ready = False
@@ -79,6 +80,7 @@ class SettingsWindow(QDialog):
self.stack.addWidget(self._page_startup())
self.stack.addWidget(self._page_cache())
self.stack.addWidget(self._page_donate())
+ self.stack.addWidget(self._page_about())
self.stack.addWidget(self._page_initialization())
# 此时 stack 已就绪,允许导航回调正常工作
self._nav_ready = True
@@ -241,11 +243,24 @@ class SettingsWindow(QDialog):
self._autostart_check.toggled.connect(self._on_autostart)
layout.addWidget(self._autostart_check)
- layout.addWidget(self._divider())
+ layout.addStretch()
+ return page
+
+ def _page_about(self) -> QWidget:
+ page = QWidget()
+ layout = QVBoxLayout(page)
+ layout.setContentsMargins(24, 20, 24, 20)
+ layout.setSpacing(16)
+
layout.addWidget(self._section_title("关于"))
- about = QLabel(f"{APP_NAME} v{__VERSION__}\n整理你的桌面快捷方式,保持桌面干净。")
- about.setStyleSheet("color:#888; font-size:12px; line-height:1.6;")
+ about = QLabel(
+ f"{APP_NAME} v{__VERSION__}
"
+ "整理你的桌面快捷方式,保持桌面干净。
"
+ "快捷键:Alt + ` 唤醒 / 隐藏主界面"
+ )
+ about.setStyleSheet("color:#888; font-size:12px; line-height:1.8;")
+ about.setTextFormat(Qt.TextFormat.RichText)
layout.addWidget(about)
layout.addStretch()