Qt中的单例模式来啦

简介:

总的来说,需要完成那些事呢?


  1. 首先,您需要在QML脚本中使用pragma Singleton关键字,
  2. 然后您需要将该组件注册为单例,
  3. 最后您需要将它导入到需要使用他的其它QML文件中。

第一步:将一个QML组件声明为单例

假设以下使我们将要进行单例的文件

//MyStyleObject.qml
import QtQuick 2.0  

Item {  
    readonly property string colourBlue: "blue"  
    readonly property string colourRed: "red"  
    readonly property int fontPointSize: 16  
} 

    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

要将其进行单例化,首先您需要在首行添加如下语句

//MyStyleObject.qml
pragma Singleton  //注意这里
import QtQuick 2.0  

Item {  
    readonly property string colourBlue: "blue"  
    readonly property string colourRed: "red"  
    readonly property int fontPointSize: 16  
} 

    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

第二步:注册组件

现在您有两种选择

  • 您可以在C++中注册组件,
  • 或者使用qmldir文件。

C++中实现

要在您的C ++代码的某个地方通过C ++注册单例,您需要调用qmlRegisterSingletonType()

#include <QtQml>  
...  
qmlRegisterSingletonType( QUrl("file:///absolute/path/MyStyleObject.qml"), "ca.imaginativethinking.tutorial.style", 1, 0, "MyStyle" );  
... 

    
    
  • 1
  • 2
  • 3
  • 4

QML中实现

如果将调用添加到qmlRegisterSingletonType()不适用于您,也许这是一个Qt Quick UI项目(即没有C ++),那么您可以将名为qmldir的文件添加到MyStyleObject.qml文件所在的目录。 在导入目录时,QML引擎首先查找qmldir文件并使用它导入在该目录中找到的脚本; 如果该文件不存在,它将导入使用默认值(即非单例并使用文件名称作为组件名称)找到的脚本。 qmldir文件可以定义不同的名称来代替文件名,还可以指示将脚本注册为单例。

目录结构应该如下所示:

/root
  + absolute
  |  + path
  |  |  + qmldir
  |  |  + MyStyleObject.qml
  |  |  + AnotherObject.qml
  |  |  + MyButton.qml
  |  |  + MySwitch.qml
  |  + main.qml


    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

以下是qmldir应该有的样子:

singleton MyStyle 1.0 MyStyleObject.qml  
MyOtherObject 1.0 AnotherObject.qml  
MyButton 1.0 MyButton.qml  


    
    
  • 1
  • 2
  • 3

请注意,如果在目录中找到脚本但未在qmldir文件中声明脚本,它仍会导入,但使用默认设置。 MySwich.qml将被导入并使用名称MySwitch注册为非单例。 您可以在这里看到,我们也可以使用qmldir来定义组件的文件名之外的其他名称,MyButton被注册为使用默认的文件名,但AnotherObject.qml被注册为使用名称MyOtherObject。


第三步:导入并使用单例

C++中实现

如果您使用上面的C ++选项,那么为了在您的QML脚本中导入和使用单例,您需要通过qmlRegisterSingletonType()的第二个参数导入您定义的模块,然后使用注册名称(参数三qmlRegisterSingletonType))。

//main.qml
import QtQuick 2.0  
import wanywhn.style 1.0  

Rectangle {  
    anchors.fill: parent  
    color: MyStyle.colourBlue // <-- 注意这里
} 

    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

QML中实现

如果您使用qmldir方法,那么您只需导入文件所在的目录。

//main.qml
import QtQuick 2.0  
import "path"  

Rectangle {  
    anchors.fill: parent  
    color: MyStyle.colourBlue // <-- 注意这里
} 

    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

但是请注意,如果main.qml位于路径目录中,您仍然必须导入该路径,因为当您依靠自动查找时,qmldir文件不会被使用。

那么使用效果如何呢?

代码地址
让我们尝试创建一千个方块。当然这里会有两种方式
这里写图片描述

 Component {
        id: gridDelegateUsingAnInstanceStyleObject
        Rectangle {
            width: 50
            height: width
            color: myStyle.colourBlue
            border.color: myStyle.colourRed
            border.width: myStyle.borderSize

            Text {
                anchors.centerIn: parent
                text: index
                font.pointSize: myStyle.fontPointSize
                color: myStyle.colourWhite
            }
            MyStyleObject {
                id: myStyle //<-- 注意这里,当您使用myStyle时,他指向一个实例对象
            }
        }
    }
    Component {
        id: gridDelegateUsingASingletonStyleObject
        Rectangle {
            width: 50
            height: width
            color: MyStyle.colourBlue //<-- 注意当使用MyStyle(大写字母M)时,您指的是qml目录文件中定义的单例。
            border.color: MyStyle.colourRed
            border.width: MyStyle.borderSize

            Text {
                anchors.centerIn: parent
                text: index
                font.pointSize: MyStyle.fontPointSize
                color: MyStyle.colourWhite
            }
        }
    }

    
    
  • 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

分别使用这两个delegate,使用QML 分析器查看效果
这里写图片描述

效果

这里写图片描述
这里写图片描述
不用说都清楚了吧。;)

目录
相关文章
|
7月前
|
设计模式 安全 测试技术
【C++】—— 单例模式详解
【C++】—— 单例模式详解
|
6月前
|
设计模式 安全 Java
单例模式分享
单例模式分享
26 0
|
设计模式 安全 Java
单例模式的运用
单例模式的运用
46 0
|
设计模式 Java Spring
什么场景要使用单例模式,什么场景不能使用?
经常有小伙伴问我,设计模式学了这么久,每次看到概念也都能理解。但是,就是不知道怎么用,在哪里能用?我告诉大家,设计模式,不是为了要用而用的,而是作为前人总结下来的经验,等到哪天需要用的时候,你能想起来为你所用。
107 0
|
安全 Java
原来要这么实现单例模式
原来要这么实现单例模式
59 0
|
设计模式 C#
C# 机房重构单例模式
C# 机房重构单例模式
73 0
|
存储 安全 调度
单例模式的简单介绍
单例模式的简单介绍
|
设计模式 安全 Java
回顾一下单例模式
回顾一下单例模式
|
设计模式 缓存
我学会了,单例模式
单例模式属于创建型模式,这个类型的设计模式是将 对象的创建和使用解耦了,花式的去创建对象。
131 0
我学会了,单例模式
|
设计模式 数据库 Python