QML supports the dynamic creation of objects from within JavaScript. This is useful to delay instantiation of objects until necessary, thereby improving application startup time. It also allows visual objects to be dynamically created and added to the scene in reaction to user input or other events.
见 动态场景范例 for a demonstration of the concepts discussed on this page.
There are two ways to create objects dynamically from JavaScript. You can either call Qt.createComponent() to dynamically create a Component object, or use Qt.createQmlObject() to create an object from a string of QML. Creating a component is better if you have an existing component defined in a QML document and you want to dynamically create instances of that component. Otherwise, creating an object from a string of QML is useful when the object QML itself is generated at runtime.
To dynamically load a component defined in a QML file, call the Qt.createComponent() function in the Qt object . This function takes the URL of the QML file as its only argument and creates a Component object from this URL.
Once you have a Component , you can call its createObject() method to create an instance of the component. This function can take one or two arguments:
null
							
							to this function.
						
						Here is an example. First there is
						
Sprite.qml
						
						, which defines a simple QML component:
					
import QtQuick 2.0 Rectangle { width: 80; height: 50; color: "red" }
						Our main application file,
						
main.qml
						
						, imports a
						
componentCreation.js
						
						JavaScript file that will create
						
Sprite
						
						对象:
					
import QtQuick 2.0 import "componentCreation.js" as MyScript Rectangle { id: appWindow width: 300; height: 300 Component.onCompleted: MyScript.createSpriteObjects(); }
						Here is
						
componentCreation.js
						
						. Notice it checks whether the component
						
							status
						
						is
						
Component.Ready
						
						before calling
						
							createObject()
						
						in case the QML file is loaded over a network and thus is not ready immediately.
					
var component; var sprite; function createSpriteObjects() { component = Qt.createComponent("Sprite.qml"); if (component.status == Component.Ready) finishCreation(); else component.statusChanged.connect(finishCreation); } function finishCreation() { if (component.status == Component.Ready) { sprite = component.createObject(appWindow, {x: 100, y: 100}); if (sprite == null) { // Error Handling console.log("Error creating object"); } } else if (component.status == Component.Error) { // Error Handling console.log("Error loading component:", component.errorString()); } }
						If you are certain the QML file to be loaded is a local file, you could omit the
						
finishCreation()
						
						function and call
						
							createObject()
						
						immediately:
					
function createSpriteObjects() { component = Qt.createComponent("Sprite.qml"); sprite = component.createObject(appWindow, {x: 100, y: 100}); if (sprite == null) { // Error Handling console.log("Error creating object"); } }
						Notice in both instances,
						
							createObject()
						
						is called with
						
appWindow
						
						passed as the parent argument, since the dynamically created object is a visual (Qt Quick) object. The created object will become a child of the
						
appWindow
						
						object in
						
main.qml
						
						, and appear in the scene.
					
When using files with relative paths, the path should be relative to the file where Qt.createComponent() is executed.
						To connect signals to (or receive signals from) dynamically created objects, use the signal
						
connect()
						
						方法。见
						
							连接信号到方法和信号
						
						了解更多信息。
					
It is also possible to instantiate components without blocking via the incubateObject() 函数。
If the QML is not defined until runtime, you can create a QML object from a string of QML using the Qt.createQmlObject() function, as in the following example:
var newObject = Qt.createQmlObject('import QtQuick 2.0; Rectangle {color: "red"; width: 20; height: 20}', parentItem, "dynamicSnippet1");
						The first argument is the string of QML to create. Just like in a new file, you will need to import any types you wish to use. The second argument is the parent object for the new object, and the parent argument semantics which apply to components are similarly applicable for
						
createQmlObject()
						
						. The third argument is the file path to associate with the new object; this is used for error reporting.
					
If the string of QML imports files using relative paths, the path should be relative to the file in which the parent object (the second argument to the method) is defined.
Important: When building static QML applications, QML files are scanned to detect import dependencies. That way, all necessary plugins and resources are resolved at compile time. However, only explicit import statements are considered (those found at the top of a QML file), and not import statements enclosed within string literals. To support static builds, you therefore need to ensure that QML files using Qt.createQmlObject() , explicitly contain all necessary imports at the top of the file in addition to inside the string literals.
When managing dynamically created objects, you must ensure the creation context outlives the created object. Otherwise, if the creation context is destroyed first, the bindings and signal handlers in the dynamic object will no longer work.
The actual creation context depends on how an object is created:
Component{}
							
							object is defined and
							
								createObject()
							
							or
							
								incubateObject()
							
							is called on that object, the creation context is the context in which the
							
组件
							
							is defined
						Also, note that while dynamically created objects may be used the same as other objects, they do not have an id in QML.
In many user interfaces, it is sufficient to set a visual object's opacity to 0 or to move the visual object off the screen instead of deleting it. If you have lots of dynamically created objects, however, you may receive a worthwhile performance benefit if unused objects are deleted.
Note that you should never manually delete objects that were dynamically created by convenience QML object factories (such as Loader and Repeater ). Also, you should avoid deleting objects that you did not dynamically create yourself.
						Items can be deleted using the
						
destroy()
						
						method. This method has an optional argument (which defaults to 0) that specifies the approximate delay in milliseconds before the object is to be destroyed.
					
						Here is an example. The
						
application.qml
						
						creates five instances of the
						
SelfDestroyingRect.qml
						
						component. Each instance runs a
						
							NumberAnimation
						
						, and when the animation has finished, calls
						
destroy()
						
						on its root object to destroy itself:
					
| 
application.qml
								 | import QtQuick 2.0 Item { id : container width : 500 ; height : 100 组件 .onCompleted: { var component = Qt . createComponent ( "SelfDestroyingRect.qml" ); for (var i=0; i < 5 ; i++) { var object = component . createObject ( container ); 对象 . x = ( 对象 . width + 10 ) * i ; } } } | 
| 
SelfDestroyingRect.qml
								 | import QtQuick 2.0 Rectangle { id : rect width : 80 ; height : 80 color : "red" NumberAnimation on opacity { to : 0 duration : 1000 onRunningChanged : { if (! running ) { console . log ( "Destroying..." ) rect . destroy (); } } } } | 
						另外,
						
application.qml
						
						could have destroyed the created object by calling
						
object.destroy()
						
						.
					
Note that it is safe to call destroy() on an object within that object. Objects are not destroyed the instant destroy() is called, but are cleaned up sometime between the end of that script block and the next frame (unless you specified a non-zero delay).
						Note also that if a
						
SelfDestroyingRect
						
						instance was created statically like this:
					
Item { SelfDestroyingRect { // ... } }
This would result in an error, since objects can only be dynamically destroyed if they were dynamically created.
						Objects created with
						
							Qt.createQmlObject()
						
						can similarly be destroyed using
						
destroy()
						
						:
					
var newObject = Qt.createQmlObject('import QtQuick 2.0; Rectangle {color: "red"; width: 20; height: 20}', parentItem, "dynamicSnippet1"); newObject.destroy(1000);