1

I am currently developing a desktop app using PyQt 5 and Python 3.5. Recently, I have encountered an issue while trying to dynamically add buttons to a layout. Here's what I am doing:

for i in range(len(movieList)):

        movies[i][0] = QtWidgets.QLabel("Title: " + movieList[i][0])
        movies[i][0].setGeometry(30, 50, 15, 20)
        movies[i][0].setFont(self.movieTitleFont)

        self.scrollLayout.addRow(movies[i][0])

        #If the lenght is 3 it means it has 2 available resolutions
        if len(movieList[i]) == 3:

            movies[i][1] = [QtWidgets.QPushButton(movieList[i][1][1], self), QtWidgets.QPushButton(movieList[i][2][1], self)]

            movies[i][1][0].clicked.connect(lambda: self.downloadMovie(movieList[i], movieList[i][1][1]))
            movies[i][1][0].setGeometry(0, 0, 10, 20)

            movies[i][1][1].clicked.connect(lambda: self.downloadMovie(movieList[i], movieList[i][2][1]))
            movies[i][1][1].setGeometry(10, 0, 10, 20)

            self.scrollLayout.addRow(movies[i][1][0])
            self.scrollLayout.addRow(movies[i][1][1])

        else:
            movies[i][1] = [QtWidgets.QPushButton(movieList[i][1][1], self)]
            movies[i][1][0].clicked.connect(lambda: self.downloadMovie(movieList[i], movieList[i][1][1]))
            movies[i][1][0].setGeometry(30, 50, 10, 20)

            self.scrollLayout.addRow(movies[i][1][0])

The problem I am having is that whenever all movies are loaded in my screen and I try to push one of the buttons to download said movie it will just take the last value "i" stored (in clicked.connect) so it will try to download the last movie shown. I have been working hardly to find a workaround to this but I haven't found the way.

Guido
  • 81
  • 2
  • 9

1 Answers1

1

I think if you change to partial then all will work fine

from functools import partial
...

for i in range(len(movieList)):

        movies[i][0] = QtWidgets.QLabel("Title: " + movieList[i][0])
        movies[i][0].setGeometry(30, 50, 15, 20)
        movies[i][0].setFont(self.movieTitleFont)

        self.scrollLayout.addRow(movies[i][0])

        #If the lenght is 3 it means it has 2 available resolutions
        if len(movieList[i]) == 3:

            movies[i][1] = [QtWidgets.QPushButton(movieList[i][1][1], self), QtWidgets.QPushButton(movieList[i][2][1], self)]

            movies[i][1][0].clicked.connect(partial( self.downloadMovie,movieList[i], movieList[i][1][1]))
            movies[i][1][0].setGeometry(0, 0, 10, 20)

            movies[i][1][1].clicked.connect(partial( self.downloadMovie,movieList[i], movieList[i][2][1]))
            movies[i][1][1].setGeometry(10, 0, 10, 20)

            self.scrollLayout.addRow(movies[i][1][0])
            self.scrollLayout.addRow(movies[i][1][1])

        else:
            movies[i][1] = [QtWidgets.QPushButton(movieList[i][1][1], self)]
            movies[i][1][0].clicked.connect(partial( self.downloadMovie,movieList[i], movieList[i][1][1]))
            movies[i][1][0].setGeometry(30, 50, 10, 20)

            self.scrollLayout.addRow(movies[i][1][0])
Achayan
  • 5,720
  • 2
  • 39
  • 61
  • No problem and if you want to know more about that visit this http://stackoverflow.com/questions/11828410/differences-between-functools-partial-and-a-similar-lambda – Achayan Jun 17 '16 at 23:58
  • Great! Will check it out! Thanks :) – Guido Jun 18 '16 at 01:12