繁体   English   中英

如何将QML对象引用传递给Qt C ++?

[英]How can I pass a QML object reference into Qt C++?

我试图在QML和Qt C ++中创建像jQuery的自动完成一样的小部件。 为此,我创建了一个QObject的C ++ AutoCompleteListener子项,然后将其注册为:

qmlRegisterType<AutoCompleteListener>(
    "foo.AutoCompleteListener",0,1,"AutoCompleteListener");

然后,我实例化侦听器和AutoCompleteForm如:

import QtQuick 2.5
import com.foo.AutoCompleteListener 0.1

Item {
    AutoCompleteForm { id: autocomplete_form }
    AutoCompleteListener { id: listener }
}

如何将对QML对象AutoCompleteForm的引用传递给AutoCompleteListener

我尝试将autocomplete_form字段传递到:

Q_INVOKABLE void set_autocomplete_form(QQmlComponent *autocomplete_form);

onCompleted信号上:

Item {
    AutoCompleteForm {
        id: autocomplete_form
        Component.onCompleted: {
            console.log("AutoCompleteForm completed");
            listener.set_autocomplete_form(autocomplete_form);
        }
    }
    AutoCompleteListener {
        id: listener
        Component.onCompleted: {
            console.log("AutoCompleteListener completed");
        }
    }
}

但是,即使AutoCompleteListenerAutoCompleteForm都已实例化,引用也是nullptr

Instantiating AutoCompleteListener and parent is  QObject(0x0)
qml: AutoCompleteListener completed
qml: AutoCompleteForm completed
Setting autocomplete_form =  QObject(0x0)

如何获取AutoCompleteFormAutoCompleteListener的QML父级的引用? 我想避免使用以下内容爬下整个QML层次结构:

QObject* f = mView.rootObject();->findChild<QObject *>("AutoCompleteForm");

我计划支持并行实例化多个AutoComplete小部件,因此操作QML对象的相对路径( ../AutoCompleteForm )似乎比必须爬过树更好。

如何将QML对象引用传递给Qt C ++?

你不能 ,这种语言不是为此设计的。 但您可以使用findChild和findChildren从C ++中获取引用。 但请阅读下面的真实解决方案。

另外,我认为你的问题是关于XY问题 你有一个问题X ,你认为Y解决了它,所以你要求Y.

针对原始问题的正确解决方案:

我试图在QML和Qt C ++中创建像jQuery的自动完成一样的小部件。

为了解决您的实际问题,您需要正确使用属性绑定。 QML是一种声明性语言,对命令式编程的自我痴迷使得很难直截了当。 将此模式用于QML:

AutocompleteForm{
    id: form
    text: "Search here..."
    suggestedTerms: helper.results
}
AutoCompleteHelper{
    id: helper
    searchFor: form.text
}

而对于C ++实现

class AutoCompleteHelper : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QString searchFor   READ searchFor WRITE setSearchFor NOTIFY searchForChanged)
    Q_PROPERTY(QStringList results READ results                      NOTIFY resultsChanged)
public:
    AutoCompleteHelper() {}
    virtual ~AutoCompleteHelper() {}
    QString searchFor() const { return m_searchFor; }
    QStringList results() const { return m_results; }

public slots:
    void setSearchFor(QString searchFor)
    {
        if (m_searchFor == searchFor)
            return;
        m_searchFor = searchFor;
        emit searchForChanged();

        // 1. Search for it...
        // 2. Some time later fill m_results
        // 3. Then: emit resultsChanged()
    } 
signals:
    void searchForChanged();
    void resultsChanged();

private:

    QString m_searchFor;
    QStringList m_results;
};

然后你会看到它神奇地起作用,因为一旦你改变了form.text,绑定就会在helper.searchFor中设置值,然后立即触发C ++插槽,你甚至可以瞬间做出反应,在C ++中可以发出resultsChanged( )神奇地填写form.suggestedTerms。

您会发现这种模式非常有效,因此您甚至希望通过在C ++中重新启动计时器来延迟它 此外,它还具有精美的声明和清洁。

如何获取AutoCompleteForm或AutoCompleteListener的QML父级的引用?

rootObject() - > findChild()的唯一替代方法似乎是QQmlProperty :: read 有几个read()函数重载,因此您可以更精确地指定上下文。 您必须提供要获取的对象的名称,并使其成为某个根对象的属性。 我喜欢关于QML和C ++之间接口这一主题的一般文章

要准确完成您想要的或访问某些已知属性的父级,您可以尝试QQmlContext :: parentContext以及接受上下文的QQmlProperty :: read ,然后查看空对象名称是否允许解析该对象。

您可以将其作为QVariant传递:

Q_INVOKABLE void QmlLink::pass_object(QVariant v)
{
    YourObject* tempObject = (YourObject*) v.value<void *>();

    ...
}

QML:

my_bound_property.pass_object(the_object);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM