2014-12-19 26 views
5

In QML è impossibile chiamare .disconnect() senza argomenti per un segnale:È possibile scollegare tutti gli slot da un segnale in Qt5 QML?

file:mainwindow.qml:107: Error: Function.prototype.disconnect: no arguments given 

Così come posso staccare tutti gli slot senza specificare ognuno di essi? O forse è possibile passare l'oggetto segnale a C++ e disconnetterlo in qualche modo lì? O forse esiste una soluzione alternativa?

L'obiettivo che voglio raggiungere è modificare il comportamento di un oggetto collegando diversi slot al suo segnale. Per esempio:

object.disconnect() // disconnect all slots 
object.connect(one_super_slot) 
object.disconnect() // disconnect all slots 
object.connect(another_super_slot) 

risposta

1

Okay, 5 minuti dopo la mia domanda ho fatto una soluzione: collegare solo una volta per un segnale che chiama JSObject dall'interno:

Item { 
    property var fire 

    // Any qml object. In this example it is ActionExecutor which emits actionRequest 
    ActionExecutor { 
     //signal actionRequest(int actionType) 
     onActionRequest: fire(actionType) 
    } 

    Action { 
     shortcut: "Ctrl+S" 
     text: "One action" 
     onTriggered: { 
      parent.fire = function(actionType) { 
       console.log('one slot') 
      } 
     } 
    } 

    Action { 
     shortcut: "Ctrl+X" 
     text: "Another action" 
     onTriggered: { 
      parent.fire = function(actionType) { 
       console.log('Another slot') 
      } 
     } 
    } 
} 

Affinché JS oggetto può essere riassegnato molte volte come vuoi in modo da poter cambiare il tuo comportamento riassegnando questo oggetto. Se si desidera disconnettere tutte le semplici assegnate undefined a fire. Inoltre è possibile effettuare una catena di "slot" per codice modificando a qualcosa di simile:

Item { 
    property var fire 
    property var slots: [ 
     function(actionType) { 
      console.log('1: ' + actionType) 
     }, 

     function() { 
      console.log('2: ' + actionType) 
     }, 

     function() { 
      console.log('3: ' + actionType) 
     } 
    ] 

    // Any qml object. In this example it is ActionExecutor which emits actionRequest 
    ActionExecutor { 
     //signal actionRequest(int actionType) 
     onActionRequest: fire(actionType) 
    } 

    Action { 
     shortcut: "Ctrl+S" 
     text: "One action" 
     onTriggered: { 
      parent.fire = function(actionType) { 
       console.log('calling all custom JS-slots') 

       for (var i in slots) { 
        slots[i](actionType) 
       } 
      } 
     } 
    } 
} 

quindi chiunque può implementare propria architettura del segnale slot in QML come un modello semplice osservatore javascript. Divertiti.

4

No. Ho guardato il codice sorgente in qv4objectwrapper.cpp, e si può vedere questo codice:

void QObjectWrapper::initializeBindings(ExecutionEngine *engine) 
{ 
    engine->functionClass->prototype->defineDefaultProperty(QStringLiteral("connect"), method_connect); 
    engine->functionClass->prototype->defineDefaultProperty(QStringLiteral("disconnect"), method_disconnect); 
} 

Queste sono le uniche due metodi che vengono aggiunti. Se si guarda il codice sorgente per method_disconnect(), è possibile vedere che richiede sempre uno o due parametri, incluso il nome dello slot da disconnettere.

Non c'è il disconnectAll() sfortunatamente.