diff --git a/src/superqt/collapsible/_collapsible.py b/src/superqt/collapsible/_collapsible.py index a388f2fb..69a9c983 100644 --- a/src/superqt/collapsible/_collapsible.py +++ b/src/superqt/collapsible/_collapsible.py @@ -13,8 +13,41 @@ Qt, Signal, ) -from qtpy.QtGui import QIcon, QPainter, QPalette, QPixmap -from qtpy.QtWidgets import QFrame, QPushButton, QSizePolicy, QVBoxLayout, QWidget +from qtpy.QtGui import QIcon, QPainter, QPaintEvent, QPalette, QPixmap +from qtpy.QtWidgets import ( + QApplication, + QFrame, + QSizePolicy, + QStyle, + QStyleOptionToolButton, + QStylePainter, + QToolButton, + QVBoxLayout, + QWidget, +) + + +class _GhostToolButton(QToolButton): + """Tool button that keeps a ghost appearance while checked.""" + + def __init__(self, parent: QWidget | None = None, *, title: str = "") -> None: + super().__init__(parent) + if title: + self.setText(title) + # Match QPushButton typography from main for consistent header text size. + self.setFont(QApplication.font("QPushButton")) + self.setCheckable(True) + self.setAutoRaise(True) + self.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonTextBesideIcon) + + def paintEvent(self, a0: QPaintEvent | None) -> None: + if not a0: + return super().paintEvent(a0) + option = QStyleOptionToolButton() + self.initStyleOption(option) + option.state &= ~QStyle.StateFlag.State_On + painter = QStylePainter(self) + painter.drawControl(QStyle.ControlElement.CE_ToolButtonLabel, option) class QCollapsible(QFrame): @@ -39,13 +72,11 @@ def __init__( self._is_animating = False self._text = title - self._toggle_btn = QPushButton(title) - self._toggle_btn.setCheckable(True) + self._toggle_btn = _GhostToolButton(self, title=title) self.setCollapsedIcon(icon=collapsedIcon) self.setExpandedIcon(icon=expandedIcon) self.setSizePolicy(QSizePolicy.Policy.Preferred, QSizePolicy.Policy.Maximum) - self._toggle_btn.setStyleSheet("text-align: left; border: none; outline: none;") self._toggle_btn.toggled.connect(self._toggle) # frame layout @@ -68,7 +99,7 @@ def __init__( _content.layout().setContentsMargins(QMargins(5, 0, 0, 0)) self.setContent(_content) - def toggleButton(self) -> QPushButton: + def toggleButton(self) -> QToolButton: """Return the toggle button.""" return self._toggle_btn