修复气泡底色问题
This commit is contained in:
+82
-18
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user