Можно ли отключить все слоты от сигнала в 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)

2 ответа

Решение

Хорошо, через 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, Также вы можете создать цепочку "слотов", изменив код на что-то вроде:

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. Наслаждаться.

Я посмотрел на исходный код в 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() к несчастью.

Другие вопросы по тегам