我试图在QML和Qt C ++中创建像jQuery's autocomplete这样的小部件。为此,我创建了一个AutoCompleteListener
的C ++ QObject
子项,然后将其注册为:
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");
}
}
}
但是,即使nullptr
和AutoCompleteListener
都已实例化,引用也是AutoCompleteForm
:
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
)似乎比必须爬过树更好。
答案 0 :(得分:3)
如何将QML对象引用传递给Qt C ++?
你不能,该语言不是为此而设计的。但您可以使用findChild和findChildren从C ++中获取引用。但请阅读下面的真实解决方案。
此外,我认为您的问题是 XY Problem 。你有一个问题 X ,你认为 Y 解决了它,所以你要求 Y 。
我正在尝试创建像jQuery的自动完成一样的东西 QML和Qt C ++中的小部件。
要解决真正的问题,您需要正确使用属性绑定。 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 ++中放射of resultsChanged()神奇地填充form.suggestedTerms。
您会发现此模式非常高效,因此您甚至希望通过在C ++中重新启动计时器来延迟它。此外,它还具有精美的陈述性和清洁性。
答案 1 :(得分:1)
如何获取对AutoCompleteForm的引用或 AutoCompleteListener的QML父级?
rootObject() - &gt; findChild()的唯一替代方法似乎是QQmlProperty::read。有几个read()函数重载,因此您可以更精确地指定上下文。您必须提供要获取的对象的名称,并使其成为某个根对象的属性。我喜欢关于QML和C ++之间接口这一主题的一般article。
要准确完成您想要的内容或访问某些已知属性的父级,您可以尝试QQmlContext::parentContext和QQmlProperty::read一起接受上下文,然后查看空对象名称是否允许解析该对象。
答案 2 :(得分:0)
您可以将其作为QVariant传递:
Q_INVOKABLE void QmlLink::pass_object(QVariant v)
{
YourObject* tempObject = (YourObject*) v.value<void *>();
...
}
qml:
my_bound_property.pass_object(the_object);