51 #include "qdeclarativeengine.h" |
51 #include "qdeclarativeengine.h" |
52 #include "private/qdeclarativebinding_p.h" |
52 #include "private/qdeclarativebinding_p.h" |
53 #include "private/qdeclarativebinding_p_p.h" |
53 #include "private/qdeclarativebinding_p_p.h" |
54 #include "private/qdeclarativeglobal_p.h" |
54 #include "private/qdeclarativeglobal_p.h" |
55 #include "private/qdeclarativescriptparser_p.h" |
55 #include "private/qdeclarativescriptparser_p.h" |
|
56 #include "private/qdeclarativedebugtrace_p.h" |
56 |
57 |
57 #include <QStack> |
58 #include <QStack> |
58 #include <QStringList> |
59 #include <QStringList> |
59 #include <QFileInfo> |
60 #include <QFileInfo> |
60 #include <QtCore/qdebug.h> |
61 #include <QtCore/qdebug.h> |
61 #include <QApplication> |
62 #include <QApplication> |
62 #include <QGraphicsObject> |
|
63 |
63 |
64 QT_BEGIN_NAMESPACE |
64 QT_BEGIN_NAMESPACE |
65 |
65 |
66 class QByteArray; |
66 class QByteArray; |
67 |
67 |
68 /*! |
68 /*! |
69 \class QDeclarativeComponent |
69 \class QDeclarativeComponent |
70 \since 4.7 |
70 \since 4.7 |
71 \brief The QDeclarativeComponent class encapsulates a QML component description. |
71 \brief The QDeclarativeComponent class encapsulates a QML component definition. |
72 \mainclass |
72 \mainclass |
|
73 |
|
74 Components are reusable, encapsulated QML elements with well-defined interfaces. |
|
75 They are often defined in \l {qdeclarativedocuments.html}{Component Files}. |
|
76 |
|
77 A QDeclarativeComponent instance can be created from a QML file. |
|
78 For example, if there is a \c main.qml file like this: |
|
79 |
|
80 \qml |
|
81 import Qt 4.7 |
|
82 |
|
83 Item { |
|
84 width: 200 |
|
85 height: 200 |
|
86 } |
|
87 \endqml |
|
88 |
|
89 The following code loads this QML file as a component, creates an instance of |
|
90 this component using create(), and then queries the \l Item's \l {Item::}{width} |
|
91 value: |
|
92 |
|
93 \code |
|
94 QDeclarativeEngine *engine = new QDeclarativeEngine; |
|
95 QDeclarativeComponent component(engine, QUrl::fromLocalFile("main.qml")); |
|
96 |
|
97 QObject *myObject = component.create(); |
|
98 QDeclarativeItem *item = qobject_cast<QDeclarativeItem*>(myObject); |
|
99 int width = item->width(); // width = 200 |
|
100 \endcode |
|
101 |
|
102 \sa {Using QML in C++ Applications}, {Integrating QML with existing Qt UI code} |
73 */ |
103 */ |
74 |
104 |
75 /*! |
105 /*! |
76 \qmlclass Component QDeclarativeComponent |
106 \qmlclass Component QDeclarativeComponent |
77 \since 4.7 |
107 \since 4.7 |
78 \brief The Component element encapsulates a QML component description. |
108 \brief The Component element encapsulates a QML component definition. |
79 |
109 |
80 Components are reusable, encapsulated Qml element with a well-defined interface. |
110 Components are reusable, encapsulated QML elements with well-defined interfaces. |
81 They are often defined in \l {qdeclarativedocuments.html}{Component Files}. |
111 |
82 |
112 Components are often defined by \l {qdeclarativedocuments.html}{component files} - |
83 The \e Component element allows defining components within a QML file. |
113 that is, \c .qml files. The \e Component element allows components to be defined |
84 This can be useful for reusing a small component within a single QML |
114 within QML items rather than in a separate file. This may be useful for reusing |
85 file, or for defining a component that logically belongs with the |
115 a small component within a QML file, or for defining a component that logically |
86 file containing it. |
116 belongs with other QML components within a file. |
|
117 |
|
118 For example, here is a component that is used by multiple \l Loader objects: |
87 |
119 |
88 \qml |
120 \qml |
89 Item { |
121 Item { |
90 Component { |
122 Component { |
91 id: redSquare |
123 id: redSquare |
|
124 |
92 Rectangle { |
125 Rectangle { |
93 color: "red" |
126 color: "red" |
94 width: 10 |
127 width: 10 |
95 height: 10 |
128 height: 10 |
96 } |
129 } |
97 } |
130 } |
|
131 |
98 Loader { sourceComponent: redSquare } |
132 Loader { sourceComponent: redSquare } |
99 Loader { sourceComponent: redSquare; x: 20 } |
133 Loader { sourceComponent: redSquare; x: 20 } |
100 } |
134 } |
101 \endqml |
135 \endqml |
|
136 |
|
137 Notice that while a \l Rectangle by itself would be automatically |
|
138 rendered and displayed, this is not the case for the above rectangle |
|
139 because it is defined inside a \c Component. The component encapsulates the |
|
140 QML elements within, as if they were defined in a separate \c .qml |
|
141 file, and is not loaded until requested (in this case, by the |
|
142 two \l Loader objects). |
|
143 |
|
144 The Component element is commonly used to provide graphical components |
|
145 for views. For example, the ListView::delegate property requires a Component |
|
146 to specify how each list item is to be displayed. |
|
147 |
|
148 Component objects can also be dynamically generated using |
|
149 \l{Qt::createComponent}{Qt.createComponent()}. |
102 */ |
150 */ |
103 |
151 |
104 /*! |
152 /*! |
105 \qmlattachedsignal Component::onCompleted() |
153 \qmlattachedsignal Component::onCompleted() |
106 |
154 |
544 { |
593 { |
545 } |
594 } |
546 |
595 |
547 /*! |
596 /*! |
548 \qmlmethod object Component::createObject(parent) |
597 \qmlmethod object Component::createObject(parent) |
549 Returns an object instance from this component, or null if object creation fails. |
598 |
|
599 Creates and returns an object instance of this component that will have the given |
|
600 \a parent. Returns null if object creation fails. |
550 |
601 |
551 The object will be created in the same context as the one in which the component |
602 The object will be created in the same context as the one in which the component |
552 was created. This function will always return null when called on components |
603 was created. This function will always return null when called on components |
553 which were not created in QML. |
604 which were not created in QML. |
554 |
605 |
555 Note that if the returned object is to be displayed, its \c parent must be set to |
606 If you wish to create an object without setting a parent, specify \c null for |
556 an existing item in a scene, or else the object will not be visible. The parent |
607 the \a parent value. Note that if the returned object is to be displayed, you |
557 argument is required to help you avoid this, you must explicitly pass in null if |
608 must provide a valid \a parent value or set the returned object's \l{Item::parent}{parent} |
558 you wish to create an object without setting a parent. |
609 property, or else the object will not be visible. |
559 */ |
610 */ |
560 |
611 |
561 /*! |
612 /*! |
562 \internal |
613 \internal |
563 A version of create which returns a scriptObject, for use in script. |
614 A version of create which returns a scriptObject, for use in script. |
568 */ |
619 */ |
569 QScriptValue QDeclarativeComponent::createObject(QObject* parent) |
620 QScriptValue QDeclarativeComponent::createObject(QObject* parent) |
570 { |
621 { |
571 Q_D(QDeclarativeComponent); |
622 Q_D(QDeclarativeComponent); |
572 QDeclarativeContext* ctxt = creationContext(); |
623 QDeclarativeContext* ctxt = creationContext(); |
573 if(!ctxt) |
624 if(!ctxt && d->engine) |
|
625 ctxt = d->engine->rootContext(); |
|
626 if (!ctxt) |
574 return QScriptValue(QScriptValue::NullValue); |
627 return QScriptValue(QScriptValue::NullValue); |
575 QObject* ret = create(ctxt); |
628 QObject* ret = create(ctxt); |
576 if (!ret) |
629 if (!ret) |
577 return QScriptValue(QScriptValue::NullValue); |
630 return QScriptValue(QScriptValue::NullValue); |
578 |
631 |
579 QGraphicsObject* gobj = qobject_cast<QGraphicsObject*>(ret); |
632 |
580 bool needParent = (gobj != 0); |
633 if (parent) { |
581 if(parent){ |
|
582 ret->setParent(parent); |
634 ret->setParent(parent); |
583 if (gobj) { |
635 QList<QDeclarativePrivate::AutoParentFunction> functions = QDeclarativeMetaType::parentFunctions(); |
584 QGraphicsObject* gparent = qobject_cast<QGraphicsObject*>(parent); |
636 |
585 if(gparent){ |
637 bool needParent = false; |
586 gobj->setParentItem(gparent); |
638 |
|
639 for (int ii = 0; ii < functions.count(); ++ii) { |
|
640 QDeclarativePrivate::AutoParentResult res = functions.at(ii)(ret, parent); |
|
641 if (res == QDeclarativePrivate::Parented) { |
587 needParent = false; |
642 needParent = false; |
|
643 break; |
|
644 } else if (res == QDeclarativePrivate::IncompatibleParent) { |
|
645 needParent = true; |
588 } |
646 } |
589 } |
647 } |
590 } |
648 |
591 if(needParent) |
649 if (needParent) |
592 qWarning("QDeclarativeComponent: Created graphical object was not placed in the graphics scene."); |
650 qWarning("QDeclarativeComponent: Created graphical object was not placed in the graphics scene."); |
|
651 } |
593 |
652 |
594 QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(d->engine); |
653 QDeclarativeEnginePrivate *priv = QDeclarativeEnginePrivate::get(d->engine); |
595 QDeclarativeData::get(ret, true)->setImplicitDestructible(); |
654 QDeclarativeData::get(ret, true)->setImplicitDestructible(); |
596 return priv->objectClass->newQObject(ret, QMetaType::QObjectStar); |
655 return priv->objectClass->newQObject(ret, QMetaType::QObjectStar); |
597 } |
656 } |
858 void QDeclarativeComponentPrivate::completeCreate() |
923 void QDeclarativeComponentPrivate::completeCreate() |
859 { |
924 { |
860 if (state.completePending) { |
925 if (state.completePending) { |
861 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); |
926 QDeclarativeEnginePrivate *ep = QDeclarativeEnginePrivate::get(engine); |
862 complete(ep, &state); |
927 complete(ep, &state); |
|
928 |
|
929 QDeclarativeDebugTrace::endRange(QDeclarativeDebugTrace::Creating); |
863 } |
930 } |
864 } |
931 } |
865 |
932 |
866 QDeclarativeComponentAttached::QDeclarativeComponentAttached(QObject *parent) |
933 QDeclarativeComponentAttached::QDeclarativeComponentAttached(QObject *parent) |
867 : QObject(parent), prev(0), next(0) |
934 : QObject(parent), prev(0), next(0) |