Component复用对象原理(qml)

简介: 简介     Component是Qt封装好的、只暴露必要接口的QML类型,可以重复利用。一个QML组件就像一个黑盒子,它通过属性、信号、函数和外部世界交互。   一个Component既可以定义在独立的QML文件(.qml为后缀的文件)中,也可以嵌入到其他的QML文件中来定义。

简介  

  Component是Qt封装好的、只暴露必要接口的QML类型,可以重复利用。一个QML组件就像一个黑盒子,它通过属性、信号、函数和外部世界交互。

  一个Component既可以定义在独立的QML文件(.qml为后缀的文件)中,也可以嵌入到其他的QML文件中来定义。那么这两种方式分别适用于什么场景呢?这里有一个原则可以帮助我们去选择Component的定义方式:如果一个Component比较小且只在某个QML文件中使用,或者说一个Component从逻辑上来看属于某个QML文档,那么就可以采用嵌入的方式来定义该Component;如果这个Component有很多地方可以用到,也就是说复用率比较高,那么就可以采用定义在独立的QML文件中的方式。下面说明一下这两种实现Component方式的差别:

  • 嵌入式定义Component:

   要在一个QML文件中嵌入Component的定义,需要使用Component对象。

  定义一个Component与定义一个QML文件类似,Component只能包含一个顶层Item,而且在这个Item之外不能定义任何数据,除了id。 在顶层Item之内,则可以包含更多的子元素来协同工作,最终形成一个具有特定功能的组件。

  Component通常用来给一个View提供图形化组件,比如ListVIew::delegate属性就需要一个Component来指定如何显示列表的每一个项,又比如ButtonStyle::background属性也需要一个Component来指定如何绘制Button的背景。  

  Component不是Item的派生类,而是从QQmlComponent继承而来的,虽然它通过自己的顶层Item为其他的view提供可视化组件,但它本身是不可见元素。你可以这么理解:你定义的组件是一个新的类型,他必须被实例化以后才能显示。而要实例化一个嵌入在QML文件中定义的Component,则可以通过Loader。

  • 在单独文件中定义Component:

  很多时候我们把一个Component单独定义在一个QML文件中,比如Qt Qucik提供的BusyIndicator空间,其实就是在BusyIndicator中定义一个组件(BusyIndicator.qml):


Control {

    id: indicator


    /*! \qmlproperty bool BusyIndicator::running


    This property holds whether the busy indicator is currently indicating

    activity.


    \note The indicator is only visible when this property is set to \c true.


    The default value is \c true.

    */

    property bool running: true


    Accessible.role: Accessible.Indicator

    Accessible.name: "busy"


    style: Settings.styleComponent(Settings.style, "BusyIndicatorStyle.qml", indicator)

}



  可以看到BusyIndicator的代码非常简单,只是给Control元素(Qt Quick定义的私有元素,用作其他控件的基类,如ComboBox、BusyIndicator等)增加了一个属性,设置了几个值而已。

  BusyIndicator.qml文件中的顶层Item是Control,而我们使用时却是以BusyIndicator为组件名(类名)。这是定义Component的一个约定:组件名必须和QML文件名一致,且组件名的首字母必须是大写的。Qt Quick提供的多数基本元素和特性,都可以在定义组件时使用 。

  例子:在一个单独的QMl文件中定义颜色选择组件ColorPicker,对应QML文件为ColorPicker.qml,可以在其他的QMl文件中使用Cololr{...}来创建ColorPicker的实例。


import QtQuick 2.6

Rectangle {
    id: colorPicker
    width: 50
    height: 30
    signal colorPicked(color clr);

    function configureBorder() {
        colorPicker.border.width = colorPicker.focus ? 2 : 0;
        colorPicker.border.color = colorPicker.focus ? "#90D750" : "#808080";
    }

    MouseArea {
        anchors.fill: parent
        onClicked: {
            colorPicker.colorPicked(colorPicker.color);
            mouse.accepted = true;
            colorPicker.focus = true;
        }
    }

    Keys.onReturnPressed: {  // 对应Enter键
        console.log("ColorPicker:onReturnPressed");
        colorPicker.colorPicked(colorPicker.color);
        event.accepted = true;
    }

    Keys.onSpacePressed: {  // 对应Space键
        console.log("ColorPicker:onSpacePressed");
        colorPicker.colorPicked(colorPicker.color);
        event.accepted = true;
    }

    onFocusChanged: {
        console.log("ColorPicker:onFocusChanged");
        configureBorder();
    }

    Component.onCompleted: {
        console.log("ColorPicker:onCompleted");
        configureBorder();
    }
}



 在单独文件中定义Component,与嵌入式定义有明显的不同:Component对象不见了,是因为在单独文件中定义组件,不需要Component对象,只有在其他QML文件中嵌入式定义组件时才需要Component对象。

  main.qml内容:



 
 

部分内容来自《Qt Quick核心编程》


目录
相关文章
|
7月前
|
前端开发 开发者
类组件(Class component)和 函数式组件(Functional component) 之间有何区别?
类组件(Class component)和 函数式组件(Functional component) 之间有何区别?
105 0
|
1月前
Flutter 自定义组件继承与调用的高级使用方式
本文深入探讨了 Flutter 中自定义组件的高级使用方式,包括创建基本自定义组件、继承现有组件、使用 Mixins 和组合模式等。通过这些方法,您可以构建灵活、可重用且易于维护的 UI 组件,从而提升开发效率和代码质量。
131 1
|
3月前
Element table组件封装 核心:父子组件传值、传方法
本文介绍了如何基于Element UI的table组件进行二次封装,创建一个具有父子组件传值和传方法功能的自定义表格组件,并提供了封装后的组件如何引入、注册和使用的方法。
152 0
Element table组件封装 核心:父子组件传值、传方法
|
7月前
|
前端开发 JavaScript 开发者
React的函数组件与类组件:探索两者之间的区别
【4月更文挑战第25天】React提供函数组件和类组件,两者在语法、状态管理、生命周期和性能优化上有所不同。函数组件简单且易于理解,使用 Hooks 可添加状态管理;类组件支持复杂状态管理和生命周期方法,适用于需要精细控制更新的场景。随着 Hooks 的发展,函数组件功能增强,成为更多开发者的首选。选择组件类型应根据实际需求权衡。
|
缓存 JavaScript
75Vue - 使用 v-once 的低级静态组件(Cheap Static Component)
75Vue - 使用 v-once 的低级静态组件(Cheap Static Component)
33 0
|
前端开发
React中的类组件和函数组件之间有什么区别?
相同点 1、组件名首字母必须大写 2、返回的组件只能有一个根元素 3、都不能修改props
|
7月前
|
存储 JavaScript 前端开发
对象和类:JS是一种基于对象的语言,可以创建和使用自定义对象。ES6引入了类的概念,使得面向对象编程更加方便。
对象和类:JS是一种基于对象的语言,可以创建和使用自定义对象。ES6引入了类的概念,使得面向对象编程更加方便。
43 0
|
前端开发 JavaScript
写文章 类组件(Class component)和 函数式组件(Functional component)之间有何区别
写文章 类组件(Class component)和 函数式组件(Functional component)之间有何区别
53 0
【Django学习】(十三)Mixins_各种具体通用类&APIView_ViewSet_GenericViewSet_ModelViewSet类视图继承的父类区别(下)
【Django学习】(十三)Mixins_各种具体通用类&APIView_ViewSet_GenericViewSet_ModelViewSet类视图继承的父类区别(下)
|
算法 Python
【Django学习】(十三)Mixins_各种具体通用类&APIView_ViewSet_GenericViewSet_ModelViewSet类视图继承的父类区别(上)
【Django学习】(十三)Mixins_各种具体通用类&APIView_ViewSet_GenericViewSet_ModelViewSet类视图继承的父类区别