修复气泡底色问题

This commit is contained in:
李志强 2026-04-08 09:20:09 +08:00
parent 948d23074a
commit 535b83cd56
16 changed files with 111 additions and 21 deletions

11
main.py
View File

@ -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)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -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,13 +958,24 @@ 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*/"
tooltip_css = (
@ -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
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):

View File

@ -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"<b>{APP_NAME}</b> v{__VERSION__}<br><br>"
"整理你的桌面快捷方式,保持桌面干净。<br><br>"
"快捷键:<b>Alt + `</b> 唤醒 / 隐藏主界面"
)
about.setStyleSheet("color:#888; font-size:12px; line-height:1.8;")
about.setTextFormat(Qt.TextFormat.RichText)
layout.addWidget(about)
layout.addStretch()