pythonpyqtpyqt5toolbox

Change the Icon of the Selected Item of the QToolBox in PyQT


Following is the PyQT code,

from PyQt5.QtWidgets import *
import sys

class Window(QWidget):

    def __init__(self):
        QWidget.__init__(self)
        layout = QGridLayout()
        self.setLayout(layout)

        # Add toolbar and items
        toolbox = QToolBox()
        layout.addWidget(toolbox, 0, 0)
        label = QLabel()
        toolbox.addItem(label, "Students")
        label = QLabel()
        toolbox.addItem(label, "Teachers")
        label = QLabel()
        toolbox.addItem(label, "Directors")

app = QApplication(sys.argv)
screen = Window()
screen.show()
sys.exit(app.exec_())

What I want is whenever an Item in that ToolBox is selected, its icon should change from "arrow-straight" to "arrow-down" to represent that this item is currently opened and others are closed. Now, if another item is clicked, then the first item's arrow should again be changed back to arrow-straight and the item that is clicked gets its arrow changed now.

How can I accomplish this in PyQT? Be it from the designer or from the Code Logic.

EDIT: For example, look at this designer below,

enter image description here

Since the "Registration Details" is selected, so I want its arrow to be replaced with another Icon (Say "arrow down" icon). And once I select some other item in the toolbox (like View Clashes), then Registration Details' arrow should be replaced with the old arrow and View Clashes arrow should get changed to another Icon.

The code for this in Pyuic file is this,

icon = QIcon()
        icon.addFile(u":/icons/icons/arrow-right.svg", QSize(), QIcon.Normal, QIcon.Off)
        self.toolBox.addItem(self.page_2, icon, u"Registration Details")

Solution

  • You can set a default icon when adding items, and then connect the currentChanged signal in order to set the other one.

    If you create a basic list with both icons, setting the proper icon is even simpler, as you only need to cycle through all items and set the icon based on the index match.

    class Test(QtWidgets.QWidget):
        def __init__(self):
            super().__init__()
            self.arrowIcons = []
            for direction in ('right', 'down'):
                self.arrowIcons.append(QtGui.QIcon(
                    ':/icons/icons/arrow-{}.svg'.format(direction)))
    
            layout = QtWidgets.QVBoxLayout(self)
            self.toolBox = QtWidgets.QToolBox()
            layout.addWidget(self.toolBox)
            self.toolBox.currentChanged.connect(self.updateIcons)
            for i in range(5):
                self.toolBox.addItem(
                    QtWidgets.QLabel(), 
                    self.arrowIcons[0], 
                    'Item {}'.format(i + 1))
    
        def updateIcons(self, index):
            for i in range(self.toolBox.count()):
                self.toolBox.setItemIcon(i, self.arrowIcons[index == i])