修复气泡底色问题

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
+82 -18
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,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):