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 分析器查看效果
这里写图片描述

效果

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

目录
相关文章
|
6月前
Qt提升控件类为自定义类
Qt提升控件类为自定义类
218 0
|
3月前
|
安全 C++
C++ QT 单例模式
C++ QT 单例模式
46 0
|
6月前
|
C++ 存储 容器
Qt QList类和QLinkedList类 详解
Qt QList类和QLinkedList类 详解
|
设计模式 数据库连接 数据库
QT 使用单例模式
QT 使用单例模式
Unity3D-单例模式各种写法应用
Unity3D-单例模式各种写法应用
123 0
|
安全 Java
Qt单例:Qt有专门的宏Q_GLOBAL_STATIC,用来实现线程安全的单例模式
Qt单例:Qt有专门的宏Q_GLOBAL_STATIC,用来实现线程安全的单例模式
1156 0
|
设计模式 XML Unix
QT和MFC的优缺点比较
QT和MFC的优缺点比较
QT和MFC的优缺点比较
|
设计模式 编译器 计算机视觉
Qt实用技巧:设计模式之单例模式,唯一实例类通用模板
Qt实用技巧:设计模式之单例模式,唯一实例类通用模板
|
设计模式 缓存 Dart
dart设计模式之工厂模式,单例模式
工厂模式 模式分析 定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行 模式难点 模式解决问题 该模式主要解决接口选择的问题。我们明确地计划不同条件下创建不同实例时,让其子类实现工厂接口,返回的也是一个抽象的产品
466 0