pythonpysidepyside2signals-slotsqpushbutton

Qt Python - in a list of buttons change color of all buttons up until the one that was clicked


I have a list of Qt buttons like this: self.buttons = [button1, button2, button3] When one is clicked, I want all the buttons that come before the one that was clicked in the list to change their colors.

I made a for loop to loop through the buttons and connect each one to a function that I defined, but when I click a button and the connected function runs, it does not know the order of the button in the buttons list, therefore I cannot make the other buttons change colors. I was thinking that I need to somehow pass the button's id or something to the function but couldn't figure out how to do it as I cannot pass arguments to the connected function: self.button1.clicked.connect(self.change_color)

One argument is automatically passed to the connected function by Qt itself but it is the main window and it does not help my situation:

def change_color(i):  
    print(i)

Output when clicked:

<__main__.Main_Window(0x6000019e0000, name="MainWindow") at 0x11df5ccc0>

Solution

  • Add all the buttons to a QButtonGroup (using their index as id) and then connect to the group's idClicked signal. This will automatically send the index of the clicked button. Below is a simple demo that shows how to do it:

    enter image description here

    import sys, random
    from PySide2 import QtCore, QtWidgets
    
    class Window(QtWidgets.QWidget):
        def __init__(self):
            super().__init__()
            layout = QtWidgets.QVBoxLayout(self)
            self.buttons = QtWidgets.QButtonGroup(self)
            for index in range(1, 11):
                button = QtWidgets.QPushButton(f'Button {index}')
                self.buttons.addButton(button, index)
                layout.addWidget(button)
            self.buttons.idClicked.connect(self.handleButtons)
    
        def handleButtons(self, index):
            color = f'#{random.randint(0, 0xFFFFFF):06x}'
            for index in range(1, index):
                self.buttons.button(index).setStyleSheet(f'background: {color}')
    
    if __name__ == '__main__':
    
        app = QtWidgets.QApplication(sys.argv)
        window = Window()
        window.setWindowTitle('Test')
        window.show()
        sys.exit(app.exec_())