![](/img/trans.png)
[英]QML and C++ : How to pass a reference of an exported C++ object to an exported C++ class?
[英]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");
}
}
}
但是,即使AutoCompleteListener
和AutoCompleteForm
都已实例化,引用也是nullptr
:
Instantiating AutoCompleteListener and parent is QObject(0x0)
qml: AutoCompleteListener completed
qml: AutoCompleteForm completed
Setting autocomplete_form = QObject(0x0)
如何获取AutoCompleteForm
或AutoCompleteListener
的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.