# Adding an icon to a ctkCheckablePushButton is difficult

**URL:** <https://discourse.slicer.org/t/adding-an-icon-to-a-ctkcheckablepushbutton-is-difficult/38468>\
**Category:** Development\
**Created:** [September 21, 2024, 2:42pm UTC](https://discourse.slicer.org/t/adding-an-icon-to-a-ctkcheckablepushbutton-is-difficult/38468 "2024-09-21T14:42:09Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![mau\_igna\_06](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/mau_igna_06/32/9056_2.png) [@mau\_igna\_06](https://discourse.slicer.org/u/mau_igna_06)\
**Post date:** [September 21, 2024, 2:42pm UTC](https://discourse.slicer.org/t/adding-an-icon-to-a-ctkcheckablepushbutton-is-difficult/38468/1 "2024-09-21T14:42:09Z")

</div>

Does someone know why I cannot get the right side icon to not render over the text?

```auto
class CustomCheckablePushButton(ctk.ctkCheckablePushButton):
    def __init__ (self, text="", parent=None):
        super(). __init__ (parent)
        
        # Create main layout
        self._mainLayout = qt.QHBoxLayout(self)
        self._mainLayout.setContentsMargins(8, 8, 8, 8)
        self._mainLayout.setSpacing(12) # Increased spacing between text and icon
        
        # Create a widget to hold the text
        self.textLabel = qt.QLabel(text)
        self.textLabel.setWordWrap(True) # Allow text to wrap
        self.textLabel.setAlignment(qt.Qt.AlignLeft | qt.Qt.AlignVCenter)
        
        # Create a widget to hold the icon
        self.iconLabel = qt.QLabel()
        self.iconLabel.setAlignment(qt.Qt.AlignCenter)
        
        # Add widgets to main layout
        self._mainLayout.addWidget(self.textLabel, 1) # Text widget takes up remaining space
        self._mainLayout.addWidget(self.iconLabel, 0) # Icon widget doesn't expand
        
        # Store the right icon and its size
        self._rightIcon = qt.QIcon()
        self._rightIconSize = qt.QSize(32, 32) # Default size 32x32
        
        # Set size policy to allow horizontal expansion
        self.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Preferred)

    def setText(self, text):
        self.textLabel.setText(text)
        self.updateGeometry()

    def text(self):
        return self.textLabel.text()

    def setRightIcon(self, icon):
        self._rightIcon = icon
        self._updateRightIcon()

    def setRightIconSize(self, size):
        self._rightIconSize = size
        self._updateRightIcon()

    def _updateRightIcon(self):
        if self._rightIcon.isNull():
            self.iconLabel.hide()
        else:
            pixmap = self._rightIcon.pixmap(self._rightIconSize)
            self.iconLabel.setPixmap(pixmap)
            self.iconLabel.setFixedSize(self._rightIconSize)
            self.iconLabel.show()
        self.updateGeometry()

    def sizeHint(self):
        textWidth = self.textLabel.sizeHint().width()
        iconWidth = self._rightIconSize.width() if not self._rightIcon.isNull() else 0
        width = textWidth + iconWidth + self._mainLayout.spacing() + self._mainLayout.contentsMargins().left() + self._mainLayout.contentsMargins().right()
        height = max(self.textLabel.sizeHint().height(), self._rightIconSize.height()) + self._mainLayout.contentsMargins().top() + self._mainLayout.contentsMargins().bottom()
        return qt.QSize(width, height)

    def minimumSizeHint(self):
        return self.sizeHint()

    def resizeEvent(self, event):
        super().resizeEvent(event)
        self.adjustSize() # Ensure the button resizes to fit content

```

Here is my example use case:

```auto
mybutton = CustomCheckablePushButton()
mybutton.text = (
    "Update\nvisualization"
)

updatePlanningIconPath = os.path.join(DOWNLOADPATH,'update_48.jpg')

mybutton.setRightIcon(qt.QIcon(updatePlanningIconPath))
mybutton.setRightIconSize(qt.QSize(32, 32))

```

Here is a screenshot of how it renders:  
 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/8/2/8231853ec78b8ff9c4803d378389ca6d43404f3f.png)

Here is the icon:

> **[Material Symbols and Icons - Google Fonts](https://fonts.google.com/icons?selected=Material%2BSymbols%2BOutlined:update:FILL@0%3Bwght@600%3BGRAD@0%3Bopsz@48&icon.query=update&icon.size=48&icon.color=%23000000)**
>
> Material Symbols are our newest icons consolidating over 2,500 glyphs in a single font file with a wide range of design variants.

Hope you can help 🙂

---

<div class="post-metadata">

**Author:** ![mau\_igna\_06](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/mau_igna_06/32/9056_2.png) [@mau\_igna\_06](https://discourse.slicer.org/u/mau_igna_06)\
**Post date:** [September 21, 2024, 9:52pm UTC](https://discourse.slicer.org/t/adding-an-icon-to-a-ctkcheckablepushbutton-is-difficult/38468/2 "2024-09-21T21:52:04Z")

</div>

This was useful enough for me:

```auto
class checkablePushButtonWithIcon(ctk.ctkCheckablePushButton):
    def __init__ (self, text="", icon=qt.QIcon(), parent=None):
        super(). __init__ (parent)
        self.text = text
        #
        self._mainLayout = qt.QHBoxLayout(self)
        self._mainLayout.setContentsMargins(0, 0, 0, 0)
        #self._mainLayout.setSpacing(15)
        #self._mainLayout.setSpacing(300)
        #
        self.icon = icon
        self._iconSize = qt.QSize(36, 36)
        pixmap = self.icon.pixmap(self._iconSize)
        self._iconLabel = qt.QLabel()
        self._iconLabel.setAlignment(qt.Qt.AlignCenter)
        self._iconLabel.setPixmap(pixmap)
        self._iconLabel.setFixedSize(self._iconSize)
        self._mainLayout.addSpacing(self.sizeHint.width())
        self._mainLayout.addWidget(self._iconLabel)
        self.setMinimumWidth(self.sizeHint.width() + self._iconSize.width())
        self.setSizePolicy(qt.QSizePolicy.Maximum, qt.QSizePolicy.Fixed)

```
