Loader QML Type

允许从 URL 或组件动态加载子树。更多

Import Statement: import QtQuick
Inherits:

Item

属性

信号

方法

  • object setSource(url source, object properties)

详细说明

Loader 用于动态加载 QML 组件。

Loader 可以加载 QML 文件(使用source 属性)或Component 对象(使用sourceComponent 属性)。它可用于延迟创建组件,直到需要时才创建:例如,组件应按需创建,或出于性能原因,组件不应不必要地创建。

下面是一个加载器,当点击MouseArea 时,它会将 "Page1.qml "加载为一个组件:

import QtQuick

Item {
    width: 200; height: 200

    Loader { id: pageLoader }

    MouseArea {
        anchors.fill: parent
        onClicked: pageLoader.source = "Page1.qml"
    }
}

可以使用item 属性访问加载的对象。

如果sourcesourceComponent 发生变化,任何先前实例化的项目都会被销毁。将source 设置为空字符串或将sourceComponent 设置为undefined 会销毁当前加载的对象,释放资源并使加载器为空。

加载器大小行为

当用于加载可视化类型时,Loader 会应用以下大小规则:

  • 如果没有为 Loader 指定明确的大小,则在加载组件后,Loader 会自动调整为加载项的大小。
  • 如果通过设置宽度、高度或锚点明确指定了加载器的大小,则加载项的大小将调整为加载器的大小。

在这两种情况下,项目和加载器的大小都是相同的。这样可以确保锚定加载器与锚定加载项是等价的。

sizeloader.qmlsizeitem.qml
import QtQuick

Item {
  width: 200; height: 200

  Loader {
    // Explicitly set the size of the
    // Loader to the parent item's size
    anchors.fill: parent
    sourceComponent: rect
  }

  Component {
    id: rect
    Rectangle {
      width: 50
      height: 50
      color: "red"
      }
  }
}
import QtQuick

Item {
  width: 200; height: 200

  Loader {
    // position the Loader in the center
    // of the parent
    anchors.centerIn: parent
    sourceComponent: rect
  }

  Component {
      id: rect
      Rectangle {
          width: 50
          height: 50
          color: "red"
      }
  }
}
红色矩形的大小将与根项目的大小相同。红色矩形的大小为 50x50,以根项目为中心。

如果源组件不是项目类型,Loader 不会应用任何特殊的尺寸规则。

接收来自加载对象的信号

可以使用Connections 类型接收加载对象发出的任何信号。例如,下面的application.qml 加载了MyItem.qml ,并能通过Connections 对象接收来自加载项的message 信号:

应用程序.qmlMyItem.qml
import QtQuick

Item {
    width: 100; height: 100

    Loader {
       id: myLoader
       source: "MyItem.qml"
    }

    Connections {
        target: myLoader.item
        function onMessage(msg) { console.log(msg) }
    }
}
import QtQuick

Rectangle {
   id: myItem
   signal message(string msg)

   width: 100; height: 100

   MouseArea {
       anchors.fill: parent
       onClicked: myItem.message("clicked!")
   }
}

另外,由于MyItem.qml 是在加载器的范围内加载的,因此它也可以直接调用加载器或其父Item 中定义的任何函数。

焦点和关键事件

Loader 是一个焦点作用域。其focus 属性必须设置为true ,其任何子代才能获得活动焦点。(更多详情,请参阅 Qt Quick 中的键盘焦点。)在加载项中接收到的任何按键事件可能也应该是accepted ,这样它们就不会传播到 Loader 中。

例如,当MouseArea 被点击时,下面的application.qml 将加载KeyReader.qml 。注意focus 属性被设置为true ,用于加载器以及动态加载对象中的Item

应用程序.qmlKeyReader.qml
import QtQuick

Rectangle {
    width: 200; height: 200

    Loader {
        id: loader
        focus: true
    }

    MouseArea {
        anchors.fill: parent
        onClicked: {
            loader.source = "KeyReader.qml"
        }
    }

    Keys.onPressed: (event)=> {
        console.log("Captured:",
                    event.text);
    }
}
import QtQuick

Item {
    Item {
        focus: true
        Keys.onPressed: (event)=> {
            console.log("KeyReader captured:",
                        event.text);
            event.accepted = true;
        }
    }
}

加载KeyReader.qml 后,它会接受按键事件并将event.accepted 设置为true ,这样事件就不会传播到父Rectangle

QtQuick 2.0 起,加载器还可以加载非可视组件。

在视图委托中使用加载器

在某些情况下,您可能希望在视图委托中使用加载器来提高委托的加载性能。这在大多数情况下都很有效,但有一个重要的问题需要注意,那就是与组件的creation context 相关的问题。

在下面的示例中,由ListView 插入delegateComponent 的上下文中的index 上下文属性将无法被 Text 访问,因为在实例化时,Loader 将使用myComponent 的创建上下文作为父上下文,而index 并不引用该上下文链中的任何内容。

Item {
    width: 400
    height: 400

    Component {
        id: myComponent
        Text { text: index }    //fails
    }

    ListView {
        anchors.fill: parent
        model: 5
        delegate: Component {
            id: delegateComponent
            Loader {
                sourceComponent: myComponent
            }
        }
    }
}

在这种情况下,我们可以将组件内联

        delegate: Component {
            Loader {
                sourceComponent: Component {
                    Text { text: index }    //okay
                }
            }
        }

到一个单独的文件中、

        delegate: Component {
            Loader {
                source: "MyComponent.qml" //okay
            }
        }

或将所需信息显式地设置为加载器的属性(这样做是因为加载器会将自己设置为加载组件的上下文对象)。

Item {
    width: 400
    height: 400

    Component {
        id: myComponent
        Text { text: modelIndex }    //okay
    }

    ListView {
        anchors.fill: parent
        model: 5
        delegate: Component {
            Loader {
                property int modelIndex: index
                sourceComponent: myComponent
            }
        }
    }
}

另请参见 Dynamic Object Creation

属性文档

active : bool

如果加载器当前处于活动状态,则该属性为true 。此属性的默认值为true

如果加载器处于非活动状态,更改sourcesourceComponent 将不会导致项目被实例化,直到加载器被激活。

将该值设置为非活动状态将导致加载器加载的任何item 被释放,但不会影响sourcesourceComponent

非活动加载器的status 始终是Null

另请参阅 sourcesourceComponent


asynchronous : bool

该属性表示组件是否会被异步实例化。默认情况下,它是false

source 属性结合使用时,加载和编译也将在后台线程中执行。

异步加载会在多个帧中创建组件声明的对象,从而降低动画出现闪烁的可能性。异步加载时,状态将变为 Loader.Loading。整个组件创建完成后,item ,状态将变为 Loader.Ready。

当异步加载正在进行时,将此属性的值更改为false 将强制立即同步完成。如果必须在异步加载完成前访问加载器内容,则可以先开始异步加载,然后强制完成加载。

为避免看到项目逐步加载,可适当设置visible ,例如

Loader {
    source: "mycomponent.qml"
    asynchronous: true
    visible: status == Loader.Ready
}

请注意,该属性只影响对象的实例化;它与通过网络异步加载组件无关。


item : QtObject [read-only]

该属性保存当前加载的顶层对象。

QtQuick 2.0 起,Loader 可以加载任何对象类型。


progress : real [read-only]

该属性显示从网络加载 QML 数据的进度,从 0.0(未加载)到 1.0(已完成)。大多数 QML 文件都很小,因此该值会从 0 迅速变为 1。

另请参阅 status


source : url

该属性包含要实例化的 QML 组件的 URL。

QtQuick 2.0 起,Loader 可以加载任何类型的对象;它并不局限于 Item 类型。

要卸载当前加载的对象,可将此属性设为空字符串,或将sourceComponent 设为undefined 。将source 设为新的 URL 也会导致卸载由前一个 URL 创建的项。

另请参阅 sourceComponent,status, 和progress


sourceComponent : Component

该属性包含要实例化的Component

Item {
    Component {
        id: redSquare
        Rectangle { color: "red"; width: 10; height: 10 }
    }

    Loader { sourceComponent: redSquare }
    Loader { sourceComponent: redSquare; x: 10 }
}

要卸载当前加载的对象,请将此属性设置为undefined

QtQuick 2.0 起,Loader 可以加载任何类型的对象;它并不局限于 Item 类型。

另请参阅 sourceprogress


status : enumeration [read-only]

此属性表示 QML 加载的状态。它可以是

  • Loader.Null - 加载器处于非活动状态或未设置 QML 源
  • Loader.Ready - QML 源已加载
  • Loader.Loading - 当前正在加载 QML 源
  • Loader.Error - 加载 QML 源时发生错误

使用此状态提供更新或以某种方式回应状态变化。例如,您可以

  • 触发状态变化:
    State { name: 'loaded'; when: loader.status == Loader.Ready }
  • 实现onStatusChanged 信号处理器:
    Loader {
        id: loader
        onStatusChanged: if (loader.status == Loader.Ready) console.log('Loaded')
    }
  • 绑定状态值:
    Text { text: loader.status == Loader.Ready ? 'Loaded' : 'Not loaded' }

请注意,如果源文件是本地文件,初始状态将是 Ready(或 Error)。虽然在这种情况下不会出现 onStatusChanged 信号,但仍会调用 onLoaded 信号。

另请参阅 progress


信号文档

loaded()

status 变为Loader.Ready 或初始加载成功时,将发出该信号。

注: 相应的处理程序是onLoaded


方法文档

object setSource(url source, object properties)

创建给定source 组件的对象实例,该实例将具有给定的propertiesproperties 参数为可选参数。加载和实例化完成后,可通过item 属性访问该实例。

如果调用此函数时active 属性为false ,则不会加载给定的source 组件,但会缓存source 和初始properties 。当加载器变成active 时,将创建一个设置了初始propertiessource 组件实例。

以这种方式设置组件实例的初始属性值不会触发任何相关的Behavior

请注意,如果在调用此函数后但在设置加载器active 之前更改了sourcesourceComponent ,缓存的properties 将被清除。

示例

// ExampleComponent.qml
import QtQuick 2.0
Rectangle {
    id: rect
    color: "red"
    width: 10
    height: 10

    Behavior on color {
        NumberAnimation {
            target: rect
            property: "width"
            to: (rect.width + 20)
            duration: 0
        }
    }
}
// example.qml
import QtQuick 2.0
Item {
    Loader {
        id: squareLoader
        onLoaded: console.log(squareLoader.item.width);
        // prints [10], not [30]
    }

    Component.onCompleted: {
        squareLoader.setSource("ExampleComponent.qml",
                             { "color": "blue" });
        // will trigger the onLoaded code when complete.
    }
}

另见 sourceactive


© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.