是否可以在 Qt5 QML 中断开所有插槽与信号的连接?

问题描述 投票:0回答:3

在 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)
qt qml signals disconnect slot
3个回答
6
投票

不。我查看了

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 观察者模式。 享受吧。


0
投票

我没有检查 Qt 源是否已更新,但即使在 2024 年,使用 Qt 6.7,如果您在不带参数的情况下调用disconnect(),控制台中也会出现 QML 错误。

因此,我不认为人们可以断开与 JS lambda 连接的连接? 我希望当 QML 对象被销毁时,这些连接会停止触发,但我会为此添加一些逻辑保护,直到我澄清这个细节......

© www.soinside.com 2019 - 2024. All rights reserved.