es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Cómo emitir diferentes señales dependiendo del argumento recibido desde otra señal.

Estoy preparando una aplicación PySide2 que recibe datos de una base de datos. Cada vez que se cambia un valor en la base de datos, se emite una señal desde un hilo QThread. La señal contendría una lista de nombres correspondientes a señales secundarias que se deben activar.
Hasta ahora tengo el programa funcionando para una señal secundaria fija, por así decirlo. Pero no logro elegir programáticamente la señal en función de los argumentos de otra.

Mi primer intento es generar un diccionario con mis señales para poder llamarlas por su nombre. Pero ordenar las señales dentro de un diccionario o lista no funciona. Si intento:

from PySide2 import QtCore, QtGui, QtWidgets

class myapp(QtWidgets.QWidget):
    sig0 = QtCore.Signal()
    kmap = {'sig0' : QtCore.Signal() }

    def __init__(self, parent = None):
        QtWidgets.QWidget.__init__(self, parent)
        self.li = QtWidgets.QLineEdit()
        self.lo = QtWidgets.QLabel()
        ## Señal directa
        #self.li.returnPressed.connect(self.changel0)

        ## Usando señal propia
        #self.li.returnPressed.connect(self.sig0)
        #self.sig0.connect(self.changel0)

        ## Usando una señal en un array o diccionario, no funciona
        self.li.returnPressed.connect(self.kmap['sig0'])
        self.kmap['sig0'].connect(self.changel0)

        self.vl = QtWidgets.QVBoxLayout()
        self.vl.addWidget(self.li)
        self.vl.addWidget(self.lo)
        self.setLayout(self.vl)

    def changel0(self):
        text = self.li.text()
        self.lo.setText(text)

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = myapp()
    w.show()
    sys.exit(app.exec_())

fallaría, dándome el error:

AttributeError: 'PySide2.QtCore.Signal' object has no attribute 'connect'

¿Cómo podría elegir la señal a enviar dependiendo de otra variable (signal_name) entonces?

Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    Una opción podría ser usar un diccionario para mapear el nombre de la señal a su objeto correspondiente, y luego usar la función incorporada getattr para obtener el objeto de la señal según el nombre. Esto podría verse algo así:

    from PySide2 import QtCore, QtGui, QtWidgets
    
    class MiAplicacion(QtWidgets.QWidget):
        signals = {
            'sig0': QtCore.Signal(),
            'sig1': QtCore.Signal(),
            'sig2': QtCore.Signal(),
        }
    
        def __init__(self, parent=None):
            QtWidgets.QWidget.__init__(self, parent)
            self.li = QtWidgets.QLineEdit()
            self.lo = QtWidgets.QLabel()
    
            self.li.returnPressed.connect(self.handle_return_press)
            self.signals['sig0'].connect(self.handle_sig0)
            self.signals['sig1'].connect(self.handle_sig1)
            self.signals['sig2'].connect(self.handle_sig2)
    
            self.vl = QtWidgets.QVBoxLayout()
            self.vl.addWidget(self.li)
            self.vl.addWidget(self.lo)
            self.setLayout(self.vl)
    
        def handle_return_press(self):
            text = self.li.text()
            nombre_señal = self.obtener_nombre_señal(text)
            señal = getattr(self.signals, nombre_señal)
            señal.emit()
    
        def handle_sig0(self):
            self.lo.setText('sig0 activada')
    
        def handle_sig1(self):
            self.lo.setText('sig1 activada')
    
        def handle_sig2(self):
            self.lo.setText('sig2 activada')
    
        def obtener_nombre_señal(self, text):
            # Aquí puedes escribir tu lógica para determinar
            # la señal adecuada para activar según el valor de `text`.
            # Por ejemplo, podrías devolver 'sig0' si text empieza con 'a',
            # 'sig1' si text empieza con 'b', etc.
            return 'sig0'
    
    if __name__ == '__main__':
        import sys
        app = QtWidgets.QApplication(sys.argv)
        w = MiAplicacion()
        w.show()
        sys.exit(app.exec_())
    

    En este ejemplo, definimos un diccionario signals que mapea nombres de señales (claves de cadena) a sus objetos correspondientes (valores de señal). Luego usamos getattr para obtener el objeto de la señal según el nombre devuelto por el método obtener_nombre_señal, el cual puede contener cualquier lógica que necesites para determinar la señal adecuada para activar. Finalmente, usamos el método emit para activar la señal.

Comments are closed.