在Qt5 QML中,是否有可能从一个信号中断开所有的插槽?

7
在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
不行。我查看了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() 方法。


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。此外,您可以通过修改代码将一系列“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观察者模式。 享受它吧。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接