加载器 QML 类型

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

导入语句import QtQuick
继承

Item

属性

信号

方法

  • object setSource(url source, object properties)

详细描述

Loader 用于动态加载 QML 组件。

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

以下是一个当鼠标区域点击时将 "Page1.qml" 作为组件加载的 Loader

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 应用以下尺寸规则

  • 如果没有为 Loader 指定明确的尺寸,则在加载组件后,Loader 将自动调整为其尺寸。
  • 如果显式设置了 Loader 的尺寸,通过设置宽度、高度或通过锚点,则加载的项目将调整为 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,居中于根项目。

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

从已加载对象接收信号

可以使用连接类型接收从加载对象发出的信号。例如,以下application.qml加载了MyItem.qml,并且可以通过连接对象接收加载项目的message信号。

application.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是在Loader的作用域内加载的,它也可以直接调用Loader或其父级Item中定义的任何函数。

焦点和按键事件

Loader是一个焦点域。其焦点属性必须设置为true,以便其任何子项才能获得活动焦点。(有关详细信息,请参阅Qt Quick中的键盘焦点。)在加载的项目中接收到的任何按键事件也应可能被接受,这样它们就不会传播到Loader。

例如,以下application.qml鼠标区域被点击时加载KeyReader.qml。注意,Loader及其在动态加载对象中的Itemfocus属性都设置为true

application.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,这样事件就不会传播到父级矩形

从QtQuick 2.0开始,Loader也可以加载非视觉组件。

在View Delegate中使用Loader

在某些情况下,您可能希望在view delegate中使用Loader以改进代理加载性能。在大多数情况下,这很有效,但要注意与Component的创建上下文相关的一个重要问题。

在以下示例中,由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
            }
        }

或显式地将所需信息作为Loader的属性设置(这可行,因为Loader将自身设置为加载组件的上下文对象)。

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
            }
        }
    }
}

另请参阅动态对象创建

属性文档

active : bool

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

如果Loader处于非活动状态,则更改sourcesourceComponent将不会导致项实例化,直到Loader被设置为活动状态。

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

非活动加载器的状态始终为Null

另请参阅sourcesourceComponent


非阻塞的 : bool

此属性表示组件是否将以非阻塞方式实例化。默认值为 false

当与 source 属性一起使用时,加载和编译也会在后台线程中执行。

异步加载会在多个帧之间创建组件声明的对象,从而降低动画中的故障可能性。在异步加载过程中,状态将变为 Loader.Loading。一旦整个组件创建完成,item 将可用,状态将变为 Loader.Ready。

在异步加载进行时更改此属性的值到 false 将强制立即、同步完成。这允许在异步加载后强制完成,以便在异步加载完成之前访问 Loader 内容。

为了避免看到项目逐渐加载,请适当设置 visible,例如。

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

注意,此属性仅影响对象实例化;它与非网络中异步加载组件无关。


item : QtObject [只读]

此属性包含当前已加载的最高级对象。

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


progress : real [只读]

此属性表示从网络加载 QML 数据的进度,从 0.0(未加载任何内容)到 1.0(完成)。大多数 QML 文件都非常小,因此此值会快速从 0 变为 1。

另请参阅状态


source : url

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

QtQuick 2.0 以来,Loader 能够加载任何类型的对象;它不仅限于 Item 类型。

要卸载当前加载的对象,请将此属性设置为空字符串,或将 sourceComponent 设置为 undefined。将 source 设置为新 URL 也会卸载先前 URL 创建的项目。

另请参阅sourceComponent状态进度


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 类型。

另请参阅source进度


status : 枚举 [只读]

此属性表示 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' }

请注意,如果源是本地文件,状态初始将转为“准备”状态(或“错误”)。在这种情况下,不会有onStatusChanged信号,但onLoaded仍然会被调用。

另请参阅进度


信号文档

loaded()

status变成Loader.Ready或者成功完成初始加载时,会发射此信号。

注意:相应的处理程序是onLoaded


方法文档

对象 setSource(url source, 对象 properties)

创建一个具有给定source组件实例,并具有给定properties。该properties参数是可选的。在加载和实例化完成后,该实例将可通过item属性访问。

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

以这种方式设置组件实例的初始属性值将不会触发任何相关的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


© 2024 Qt公司。本文件中包含的文档贡献者拥有各自的版权。本文件提供的文档是根据GNU自由文档许可协议版1.3许可的,由自由软件基金会发布。Qt以及相关的标志是芬兰的Qt公司和其他国家的商标。所有其他商标均为各自所有者的财产。