如何从c++代码中发出特定QML项上下文中的信号

How to emit signal in context of specific QML Item from C++ code

本文关键字:QML 上下文 信号 c++ 代码      更新时间:2023-10-16

我有两个QML项目具有相同的接口(发出和处理的信号)和不同的objectName属性值:

Text {
    id: the_first_item
    objectName: "the_first_item"
    signal ping();
    onPing: {
        text = "pong! (variant 1)"
    }
}
Text {
    id: the_second_item
    objectName: "the_second_item"
    signal ping();
    onPing: {
        text = "pong! (variant 2)"
    }
}

我想在这些项目之一的上下文中发出ping信号。在QML中我会这样做:

Item {
    onSomething: the_first_item.ping()
}

问题是我想从c++代码中完成它。我有一个指向使用findChild方法和objectName属性值检索的QQuickItem类实例的指针。

处理从c++代码触发的信号的唯一解决方案是定义自己的QObject衍生物,在其主体中声明信号方法,然后简单地在该类实例的上下文中调用它:

class SomeLogic : public QObject
{
public signals:
    void ping();
public:
    void doSth() { ping(); }
};

然后,在引擎的根上下文中放置一个指向该类实例的指针,并以以下方式在QML中将处理程序连接到该信号:

Text {
    id: the_first_item
    //objectName: "the_first_item"
    Connections {
        target: the_instance_of_some_logic_property_name
        onPing: {
            text = "pong!"
        }
    }
}

但如果我理解正确,那就不好了,因为如果the_second_item以相同的方式定义,它们都将处理the_instance_of_some_logic_property_name发出的ping信号,我只想触发其中一个。

现在,当我写它的时候,我认为也许在每个项目中提供一个实用程序函数,然后在其自己的上下文中发出ping信号,像这样:

Text {
    id: the_first_item
    objectName: "the_first_item"
    signal ping();
    onPing: {
        text = "pong!"
    }
    function emitPing() {
        ping()
    }
}

在一个更简单的情况下,emitPing就足够了(我不需要定义信号和处理程序-我只会在emitPing函数中设置文本),但如果我理解正确,函数信号之间的区别是函数调用是同步的,而信号是异步的,并且由于某些原因(从QML发起的GUI状态之间的转换,但在c++中处理)我希望它是异步的。我还想避免在任何地方都写emitPing函数的必要性。

问题:是否有一种方法可以从c++代码中发出ping信号,仅在the_first_item的上下文中?

既然作为评论有帮助,现在作为回答:

您可以使用Qts元对象系统发出任何QObject的信号。在本例中,要发出the_first_itemping信号,只需调用QMetaObject::invokeMethod(the_first_item, "ping");

关于整个元对象机制的更多信息可以在这里找到:the meta - object System.