python - pyqt pip
¿Cómo es que este código solo cambia al azul?(Python, PyQt) (1)
La razón por la que connect(lambda: self.set_color(x))
no funciona es que x
se evaluará solo cuando se llame a la lambda, es decir, cuando se emita la señal, que será mucho más tarde, una vez que se haya completado el ciclo. Entonces set_color()
recibirá el valor de x
en el momento en que se emite la señal. En su código, este será el último valor que x
tenía en el ciclo, es decir, 2.
Aunque la respuesta de @Hola es válida, encuentro que la solución de Achayan (mencionada en un comentario) es más explícita y funciona bien (contrario a algunos comentarios, lo verifiqué con el código):
for x in range(0, 3):
...
self.buttons[x].clicked[bool].connect(partial(self.set_color, x))
La razón por la que esto funciona es que x
es un argumento para una llamada a función (la función es functools.partial
), por lo que x
se evalúa inmediatamente . La función devuelta por partial(f, a)
cuando f
es una función de un arg es una función g()
que no toma argumentos y llamará a f(a)
.
Por alguna razón, ejecutar este código solo cambia el color azul, cuando se supone que debe alternar cada uno de los colores individualmente.
Este código es mi versión del código de ejemplo en http://eli.thegreenplace.net/2011/04/25/passing-extra-arguments-to-pyqt-slot , que es un tutorial para PyQt, que acabo de iniciar aprendizaje.
import sys
from PyQt5.QtWidgets import (QWidget, QPushButton,
QFrame, QApplication)
from PyQt5.QtGui import QColor
class Example(QWidget):
red = False
blue = False
green = False
buttons = []
def __init__(self):
super().__init__()
self.init_UI()
def init_UI(self):
self.col = QColor(0, 0, 0)
for x in range(0, 3):
self.buttons.append(QPushButton(''Red'' if x == 0 else (''Green'' if x == 1 else ''Blue''), self))
self.buttons[x].setCheckable(True)
self.buttons[x].move(10, 10 + 50 * x)
self.buttons[x].clicked[bool].connect(lambda: self.set_color(x))
self.square = QFrame(self)
self.square.setGeometry(150, 20, 100, 100)
self.square.setStyleSheet("QWidget { background-color: %s }" %
self.col.name())
self.setGeometry(300, 300, 280, 170)
self.setWindowTitle(''Toggle button'')
self.show()
def set_color(self, button):
if button == 0:
if self.red == False:
self.red = True
self.col.setRed(255)
else:
self.red = False
self.col.setRed(0)
elif button == 1:
if self.green == False:
self.green = True
self.col.setGreen(255)
else:
self.green = False
self.col.setGreen(0)
else:
if self.blue == False:
self.blue = True
self.col.setBlue(255)
else:
self.blue = False
self.col.setBlue(0)
self.square.setStyleSheet("QFrame { background-color: %s }" %
self.col.name())
print(self.col.name())
if __name__ == ''__main__'':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())