Search code examples
pythonpyside2qpushbutton

Dynamically creating buttons and assigning click actions


I'm trying to practise by making a Pokedex. I'm trying to dynamically create a list of buttons inside of an OVBoxLayout based on the response from an API call. The list of buttons is generated correctly however, none of the buttons work, code below:

from PySide2.QtWidgets import *
from PySide2.QtCore import *
from PySide2.QtGui import *
from app.pokeapi_client import PokeApiClient


class MainWindow(QWidget):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        self.setup_styles()

        self.pokemon_list_data = PokeApiClient().get_pokemon_list(limit=9)
        self.setWindowTitle("Pokemon")
        self.resize(1000, 800)

       # create main layout
       main_layout = QHBoxLayout()

       # build list layout and populate with labels
       self.pokemon_list_layout = QVBoxLayout()
       self.populate_pokemon_list_layout()

       # add list layout to main layout
       main_layout.addLayout(self.pokemon_list_layout, 1)

       self.setLayout(main_layout)

    def populate_pokemon_list_layout(self):
        for pokemon in self.pokemon_list_data['results']:
            button = QPushButton(pokemon['name'])
            button.clicked.connect(self.print_this)
            self.pokemon_list_layout.addWidget(button)

    def print_this(self):
        print("hello world!")

    def setup_styles(self):
        self.setStyleSheet("""
            QWidget {
                background: red;
            }
            QPushButton {
                color: white;
                background: blue;
                border: 1px solid white;
            }
        """)

The button.clicked.connect() doesn't appear to be assigning the function to each button, anyone know why this might be happening?


Solution

  • Here is a MRE with your code :

    from PySide2 import QtWidgets
    from PySide2 import QtCore
    from PySide2 import QtGui
    
    DATA = {'results':[{'name':'pikka'}, {'name': 'dracofeu'}, {'name': 'mewtwo'}]}
    
    class MainWindow(QtWidgets.QWidget):
        def __init__(self, parent=None):
            super(MainWindow, self).__init__(parent)
    
            self.pokemon_list_data = DATA #Emulation data
            self.setWindowTitle("Pokemon")
            # self.resize(1000, 800)
    
            # create main layout
            main_layout = QtWidgets.QHBoxLayout()
    
            # build list layout and populate with labels
            self.pokemon_list_layout = QtWidgets.QVBoxLayout()
            self.populate_pokemon_list_layout()
    
            # add list layout to main layout
            main_layout.addLayout(self.pokemon_list_layout, 1)
            self.setLayout(main_layout)
    
    
        def populate_pokemon_list_layout(self):
            for pokemon in self.pokemon_list_data['results']:
                button = QtWidgets.QPushButton(pokemon['name'])
                button.clicked.connect(self.print_this)
                self.pokemon_list_layout.addWidget(button)
    
    
        def print_this(self):
            sender = self.sender()
            print(sender.text())
    
    
    app = QtWidgets.QApplication([])
    test = MainWindow()
    test.show()
    app.exec_()
    

    Here is the result : enter image description here As you can see I didn't change anything (except imports and the sender in the print_this method) but it works. I think you have a problem somewhere in your code.