• 【qml】QML | 创建自定义组件(02)


    开篇

    在《QML | 创建可重用的组件》一文中,描述了创建自定义组件的第一种方法。本文将来描述第二种方法:

    使用Component创建自定义组件

    该种方法在实际使用中,可有两种方式:

    • (1)在qml文件内创建自定义的组件

    • (2)以qml文件的方式创建组件。

    在qml文件内创建自定义的组件

    组件通常由组件文件定义,也就是.qml文件。Component类型允许在一个QML文档内定义QML组件,而不用作为一个单独的QML文件,例如如下代码:

    该组件的封装代码是放置于main.qml这个应用根描述文件中的,我们运行一下:


    将得到一个空白的窗体。

    如果我们要使用这个组件,我们可以使用Loader类型,该QML类型用于:动态加载QML组件。

    这时候会动态加载这个组件,运行则可以看见一个蓝色的矩形:

    也可以使用Loader创建多个矩形:

    运行效果如下:

    综上可见,虽然矩形本身会自动渲染和显示,但在Component中定义的则不会这样。因为Component将QML类型封装在内部,就好像它们是在一个单独的QML文件中定义的,直到请求时(在本例中,使用Loader类型)才加载。理解了这一点,如果代码这些写:

    结果则是:无法运行程序。因为这种写法在本质上是没有QML根元素的。因此需注意:

    在Component类型封装的QML组件中不能存在多个同级的QML类型,只能存在一个根元素。

    使用Component在qml文件内创建组件不能直接实例化,可以结合:Loader、Repeater、View视图、脚本来使用。下文将描述使用Component创建多个qml组件。

    使用Component创建多个qml组件

    使用Component创建多个qml组件在实际的QML应用开发中是一种较为常用的方法,因为一个应用软件,会包含多个软件UI,例如下图所示效果:


    在上图所示的窗体中会有四个按钮,分别为:page_1、page_2、page_3、page_4。当我们在点击其中的按钮后,会跳转到对应的页面,然而在页面中又有其他的QML类型和逻辑。这时候则需要使用Component来封装不同页面的组件。以上图效果为例,则需要创建四个不同的页面描述qml文件,这里文件名称如下:

    然后使用Component创建四个页面qml组件,例如下例代码:

    在实际开发中,对于不同的页面参数有所不同的,还可以将属性导出,在对应的组件实例下设置参数,从而设置不同的页面参数。

    运行看一下效果:

    附上main.qml文件代码:

    import QtQuick 2.2
    import QtGraphicalEffects 1.0
    import QtQuick.Controls 1.4
    import QtQuick.Controls.Styles 1.4
    import QtQuick.Dialogs 1.0
    import QtQuick.Extras 1.4
    import QtQuick.Layouts 1.0
    import QtQuick.Window 2.1
    
    Window {
        id: window
        visible: true
        width: 350
        height: 500
    
        title: qsTr("iriczhao | 使用Component创建组件")
    
        //页面一
        property Component page1: Page1View{}
    
        //页面二
        property Component page2: Page2View{}
    
        //页面三
        property Component page3: Page3View{}
    
        //页面四
        property Component page4: Page4View{}
    
        //创建组件映射
        property var componentMap: {
            "page_1": page1,
            "page_2": page2,
            "page_3": page3,
            "page_4": page4
        }
    
        //创建StackView
        StackView {
            id: stackView
            anchors.fill: parent
    
            initialItem: ListView {
                model: ListModel {
                    ListElement {
                        title: "page_1"
                    }
                    ListElement {
                        title: "page_2"
                    }
                    ListElement {
                        title: "page_3"
                    }
                    ListElement {
                        title: "page_4"
                    }
                }
    
                delegate: Button {
                    width: stackView.width
                    height: 50
                    text: title
    
                    style: BlackButtonStyle {
                        fontColor: "#e7e7e7"
                        rightAlignedIconSource: "qrc:/images/icon-go.png"
                    }
    
                    onClicked: {
                        if (stackView.depth == 1) {
                            stackView.push({item: componentMap[title]});
                            stackView.currentItem.forceActiveFocus();
                        }
                    }
                }
            }
        }
    
        //创建返回按钮
        Button{
            x: 138
            y: 409
            text: "return"
            anchors.bottom: stackView.top
            anchors.bottomMargin: -432
    
            onClicked: {stackView.pop({item: componentMap[title]});}
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90

    总结

    本文使用Component来创建自定义组件,准确来说,应该是创建和加载组件。我们可以在单个qml文件中使用Component创建组件,然后使用Loader、Repeater来加载组件;也可以将组件划分为具体的qml文件(即以qml文件来表示单个组件),然后再使用Component来加载。

  • 相关阅读:
    C语言基础
    B. Bin Packing Problem(线段树+multiset)
    中霖教育:注册安全工程师考是科目有哪些?
    基于go-zero的rpc服务示例
    QT+OSG/osgEarth编译之五十四:osgUI+Qt编译(一套代码、一套框架,跨平台编译,版本:OSG-3.6.5工具库osgUI)
    多节点树的层序遍历
    异构数据源同步之表结构同步 → 通过 jdbc 实现,没那么简单
    Pyside6 QRadioButton
    福州大学 2022~2023 学年第 1 学期考试 A 卷压轴题参考答案
    聊聊DisposableBeanAdapter
  • 原文地址:https://blog.csdn.net/iriczhao/article/details/126533885