"Si un ouvrier veut bien faire son travail, il doit d'abord affûter ses outils." - Confucius, "Les Entretiens de Confucius. Lu Linggong"
Page de garde > La programmation > Pourquoi mon signal cliqué sur le bouton PyQt4 génère-t-il toujours la même valeur dans une boucle ?

Pourquoi mon signal cliqué sur le bouton PyQt4 génère-t-il toujours la même valeur dans une boucle ?

Publié le 2024-11-16
Parcourir:670

Why Does My PyQt4 Button Clicked Signal Always Output the Same Value Within a Loop?

Connexion des slots et des signaux dans PyQt4 dans une boucle

Dans PyQt4, l'établissement de connexions entre les slots et les signaux est un aspect fondamental de la gestion des événements. Cependant, lorsque vous tentez de connecter plusieurs signaux émis par des boutons dans une boucle, un comportement inattendu peut survenir.

Pour illustrer ce problème, considérez le code suivant :

def __init__(self):
    for i in range(0, 10):
        self._numberButtons  = [QPushButton(str(i), self)]
        self.connect(self._numberButtons[i], SIGNAL('clicked()'), lambda: self._number(i))

def _number(self, x):
    print(x)

Lorsque vous cliquez sur l'un des boutons, la sortie affiche systématiquement « 9 », quel que soit le bouton sur lequel vous avez appuyé. Comprendre la raison de ce comportement implique d'explorer les subtilités des règles de portée de Python.

En Python, la portée d'une variable est déterminée par la fonction englobante la plus proche. Dans cet exemple, la fonction lambda et la fonction « _number » sont définies dans la fonction « __init__ ». Étant donné que la boucle attribue la même valeur (« 9 ») à « i » pour chaque itération, la fonction lambda capture toujours la dernière valeur attribuée à « i » dans la fonction « __init__ », qui est « 9 ».

Pour résoudre ce problème, une approche consiste à transmettre « i » comme argument de mot-clé avec une valeur par défaut dans la fonction lambda, en garantissant qu'une liaison distincte de « i » est créée pour chaque instance.

self._numberButtons[i].clicked.connect(lambda checked, i=i: self._number(i))

Alternativement, functools.partial peut être utilisé pour créer un fonction spécialisée qui lie « i » à la valeur spécifique associée à chaque bouton.

self._numberButtons[i].clicked.connect(partial(self._number, i))

Ces modifications garantissent que chaque fonction de rappel capture la valeur correcte de « i », permettant des réponses appropriées aux clics sur les boutons.

Dernier tutoriel Plus>

Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.

Copyright© 2022 湘ICP备2022001581号-3