我正在通过以下代码创建一个新窗口:
QMainController* myController = new QMainController(0,m_autenticado);
QQmlApplicationEngine* engine = new QQmlApplicationEngine(this);
engine->rootContext()->setContextProperty("MyController", myController);
engine->load(QUrl(QStringLiteral("qrc:///newPage.qml")));
QQuickWindow* window = qobject_cast<QQuickWindow*>(engine->rootObjects().at(0));
window->showFullScreen();
此代码将 MyController 属性设置为rootContext,这意味着根上下文中的所有页面都可以访问此属性。因此,这不允许我从同一个QML文件中打开2个不同的窗口,每个窗口都有自己的MainController实例。
问题:如何将此 MyController 属性绑定到QQuickWindow上下文而不是引擎的rootContext?
我尝试使用QQuickView,并且这样做:
QMainController* myController = new QMainController(0,m_autenticado);
QQuickView* view = new QQuickView();
view->rootContext()->setContextProperty("MyController", myController );
view->setSource(QUrl(QStringLiteral("qrc:///main.qml")));
view->showFullScreen();
但我抱怨以下信息:
&#34; QQuickView仅支持加载从QQuickItem派生的根对象。
如果您的示例使用的是QML 2(例如qmlscene)和.qml文件 已加载导入QtQuick 1.0&#39;或者&#39;导入Qt 4.7&#39;,将发生此错误。
使用&t;导入QtQuick 1.0&#39;加载文件或者&#39;导入Qt 4.7&#39;,使用 Qt Quick 1模块中的QDeclarativeView类。&#34;
答案 0 :(得分:11)
QQuickWindow
不拥有自己的任何上下文属性,因此无法使用它设置上下文属性。
正如消息所解释的那样,QQuickView
期望从QQuickItem
继承QML根对象,这意味着根可以是Rectangle
,Item
等,但是不是ApplicationWindow
或Window
,因为它们不是从QQuickItem
继承的。如果您可以将根对象更改为Rectangle
之类的内容,则可以创建QQuickView
的不同实例来实现目标,因为每个QQuickView
创建自己的QQmlEngine
如果您没有&# 39; t为其提供现有的QQmlEngine
。
QQmlApplicationEngine
实际上继承自QQmlEngine
,因此每个实例都有自己的根上下文。例如,调用以下createMain()
两次将创建两个具有单独引擎的窗口,单独的控制器和单独的rootContext:
void foo::createMain() {
//TODO: Set a proper parent to myController
QMainController* myController = new QMainController(0,m_autenticado);
QQmlApplicationEngine* engine = new QQmlApplicationEngine(this);
engine->rootContext()->setContextProperty("MyController", myController);
engine->load(QUrl(QStringLiteral("qrc:///newPage.qml")));
QQuickWindow* window = qobject_cast<QQuickWindow*>(engine->rootObjects().at(0));
window->showFullScreen();
}
如果您不想创建QQmlAppicationEngine
的多个副本,则可以共享QQmlApplicationEngine
的一个实例,并为每个窗口实例创建子上下文:
// foo.h
class foo {
private:
QQmlApplicationEngine m_engine; // can change to QQmlEngine if you prefer
}
// foo.cpp
void foo::createMain()
{
//TODO: Set a proper parent to myController
QMainController* myController = new QMainController(0,m_autenticado);
// Create a new context as a child of m_engine.rootContext()
QQmlContext *childContext = new QQmlContext(&m_engine, &m_engine);
childContext->setContextProperty("MyController", myController);
QQmlComponent *component = new QQmlComponent(&m_engine, &m_engine);
component->loadUrl(QUrl("qrc:///qml/newPage.qml"));
// Create component in child context
QObject *o = component->create(childContext);
QQuickWindow* window = qobject_cast<QQuickWindow*>(o);
window->show();
}
当然,如果没有使用QQmlApplicationEngine的功能,您可以将QQmlApplication
更改为QQmlEngine
。