Можно ли отключить все слоты от сигнала в Qt5 QML?

В QML нельзя вызывать .disconnect() без аргументов для сигнала:

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

Так как же отключить ВСЕ слоты, не указывая каждый из них? Или, может быть, можно передать сигнальный объект в C++ и отключить его как-то там? Или, может быть, существует какой-либо обходной путь?

Цель, которую я хочу достичь, - изменить поведение объекта, подключив разные слоты к его сигналу. Например:

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

person Victor Polevoy    schedule 19.12.2014    source источник


Ответы (2)


Нет. Я посмотрел исходный код в qv4objectwrapper.cpp, и вы можете увидеть этот код:

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

Это единственные два метода, которые добавляются. Если вы посмотрите на исходный код для method_disconnect(), вы увидите, что он всегда требует один или два параметра, включая имя слота для отключения.

disconnectAll() к сожалению нет.

person Timmmm    schedule 10.06.2015

Хорошо, через 5 минут после моего вопроса я сделал обходной путь: подключился только один раз к одному сигналу, который вызывает jsobject изнутри:

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')
            }
        }
    }
}

Так что объект js можно переназначать много раз, когда вы хотите, поэтому вы можете изменить свое поведение, переназначив этот объект. Если вы хотите отключить все, просто назначьте undefined на fire. Также вы можете создать цепочку «slots», изменив код примерно так:

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)
                }
            }
        }
    }
}

Таким образом, любой может реализовать собственную архитектуру сигнального слота в qml как простой шаблон наблюдателя javascript. Наслаждаться.

person Victor Polevoy    schedule 19.12.2014