QML Options
Categories:
4 分钟阅读
理解你的需求,以下是 QML 中顶层容器的不同类型,以及它们适用于哪些场景:
顶层容器类型
示例代码
以下是每个顶层容器的简单示例:
1. ApplicationWindow
import QtQuick 6.2
import QtQuick.Controls 6.2
ApplicationWindow {
visible: true
width: 800
height: 600
title: "ApplicationWindow Example"
}
2. Window
import QtQuick 6.2
import QtQuick.Window 6.2
Window {
visible: true
width: 800
height: 600
title: "Window Example"
}
3. Dialog
import QtQuick 6.2
import QtQuick.Controls 6.2
Dialog {
visible: true
width: 400
height: 300
title: "Dialog Example"
standardButtons: Dialog.Ok | Dialog.Cancel
}
4. Popup
import QtQuick 6.2
import QtQuick.Controls 6.2
Popup {
visible: true
width: 200
height: 100
Text {
anchors.centerIn: parent
text: "Popup Example"
}
}
5. Item
import QtQuick 6.2
Item {
width: 800
height: 600
Rectangle {
width: 100
height: 100
color: "blue"
}
}
6. Rectangle
import QtQuick 6.2
Rectangle {
width: 800
height: 600
color: "lightgray"
Text {
anchors.centerIn: parent
text: "Rectangle Example"
}
}
7. Application
import QtQuick 6.2
Application {
id: app
Item {
width: 800
height: 600
Rectangle {
width: 100
height: 100
color: "blue"
}
}
}
顶层容器结构
顶层容器的结构通常如下:
Application 或 ApplicationWindow 或 Window 或 Dialog 或 Popup
子元素:Item, Rectangle, Text, Button, ListView 等各种 UI 元素
示例:
ApplicationWindow {
visible: true
width: 800
height: 600
title: "App Structure Example"
Rectangle {
width: parent.width
height: parent.height
color: "lightgray"
Text {
anchors.centerIn: parent
text: "Hello, World!"
}
}
}
这些顶层容器类型及其结构可以根据具体需求选择和使用,从而满足不同类型的应用程序设计需求。
关键字:Property
让我们深入探讨一下 QML 中 property 的作用、外部访问的机制,以及如何决定属性是否暴露给外部。
1. QML 中的属性访问机制
内置属性(如 height、width 等)
内置属性:QML 中的某些属性,如
height、width、color等,是组件自带的内置属性,这些属性默认是对外暴露的。因此,父组件可以直接访问和设置这些属性。访问方式:这些内置属性在定义组件时自动提供,可以直接通过组件的
id在外部访问,例如:
Rectangle {
id: rect
width: 100
height: 50
}
Item {
width: rect.width // 直接访问 rect 的 width 属性
}
2. property 的作用
定义自定义属性
- 扩展属性:通过
property,你可以定义组件的自定义属性,这些属性不是组件的内置属性。property使得这些自定义属性能够被外部访问和修改。例如,你可能会定义一个property来跟踪某个状态:
Rectangle {
id: rect
property int myCustomHeight: 100
}
Item {
width: rect.myCustomHeight // 访问自定义的 myCustomHeight 属性
}
绑定和初始值
- 属性绑定:
property可以与其他属性或表达式绑定,这使得属性之间能够自动更新。例如:
Rectangle {
id: rect
property int myCustomHeight: width / 2 // myCustomHeight 随着 width 的变化而变化
width: 200
}
暴露内部状态
- 状态管理:你可以通过
property把组件的内部状态暴露给外部,从而实现更好的封装和模块化设计。例如,定义一个property来暴露内部的计算结果:
Rectangle {
id: rect
property real area: width * height // 暴露矩形的面积
}
3. 内部变量与 property 的区别
局部变量:如果你只需要在组件内部使用某个值或状态,通常不会使用
property,而是使用局部变量或 JavaScript 变量。局部变量不会暴露给外部,也不会通过id访问到。- 局部变量示例:
Rectangle { id: rect width: 100 height: 50 var internalValue = 200 // 只在这个组件内部可见的变量 }
- 局部变量示例:
property的作用:property主要用于定义和管理组件的外部可见状态或配置。通过property,你可以把组件的某些内部状态暴露出来,供父组件或外部组件访问。
4. 总结:property 的功能与外部访问
外部访问:内置属性(如
height、width)默认是暴露给外部的,而通过property定义的属性也会暴露给外部。没有property修饰的局部变量则不会被外部访问到。property的用途:property主要用于定义组件的自定义属性、管理属性绑定、或暴露内部状态给外部。property还允许你为自定义属性设置初始值,并支持动态绑定。局部变量 vs
property:如果你不希望某个状态或值被外部访问,且只需要在组件内部使用,那么应使用局部变量或 JavaScript 变量,而不是property。property用于那些需要外部访问和管理的属性。
通过理解这些概念,你可以更好地设计和组织 QML 代码,确保组件之间的低耦合性和良好的封装性。
003.Singleton 单例对象
使用场景
可以是要在外部动态的设置某一个程序的属性,让整个程序的其他组件都因此做出改变,可以用singleton
希望精简,模块不要反复被创建
【必要步骤】在相应的qml文件的顶行写pragma Singleton
pragma Singleton
注意这条语句要写在import 语句之前
【必要步骤】需要在相应的CMakeList.txt里设置QT_QML_SINGLETON_TYPE 为TRUE
set_source_files_properties(First_Color_Scheme.qml PROPERTIES
QT_QML_SINGLETON_TYPE TRUE
)
在哪一个CMakeList.txt呢?
我的qml文件处在项目根目录下的一个叫content的文件夹中
这个文件夹是专门存放所有qml文件的
在content下有一个CMakeList.txt
(不要放到项目根目录下的CMakeList.txt里面-因为放进去也没用)
设置完会怎么样,请看build之后的目录下:
build\6_5_3_MSVC2019_x64-Debug\qml\content\qmldir

设置技巧
本语句的位置不能低于qt6_add_qml_module(或qt_add_qml_module)

【必要步骤】需要在相应的CMakeList.txt里创建单例模块Singleton Module(独立于其他QML模块)
- CMakeLists.txt的相关代码
qt6_add_qml_module(singleton
URI "singleton"
VERSION 1.0
QML_FILES
Color/First_Color_Scheme.qml
)
这里的URI很重要,最后我们要调用的地方,都需要import,而import后面的模块名称就是看URI的。
为什么一定要再这里创建单例模块呢?
按照微软的文档:

我们就是需要去把它做成一个模块的
【必要步骤】调用singleton object(单例对象)的办法
不能用的办法1:创建它
代码
Second_TitleBar { id: bID_Instance_Module_TitleBar anchors.top: parent.top width: parent.width }例如这种方法,就是去创建一个单例对象,这样会提示错误

错误信息
11:00:01: Starting C:\Code\ASCtl\PL\QtProj\build\6_5_3_MSVC2019_x64-Debug\ASCtl_UIApp.exe... DLL_PROCESS_ATTACH: The DLL has been attached to the process at 00007FF902D40000 QML debugging is enabled. Only use this in a safe environment. Ext_CreateAudioControl called. ASCtl_Impl constructor called. QQmlApplicationEngine failed to load component qrc:/qt/qml/Main/main.qml:7:1: Type App unavailable qrc:/qt/qml/content/App.qml:54:1: Type VolumeMixer unavailable qrc:/qt/qml/content/VolumeMixer.qml:20:5: Composite Singleton Type Second_TitleBar is not creatable. DLL_PROCESS_DETACH: The DLL has been detached from the process at 00007FF902D40000 11:00:01: C:\Code\ASCtl\PL\QtProj\build\6_5_3_MSVC2019_x64-Debug\ASCtl_UIApp.exe exited with code -1
可能可以用的办法:把某个要作为单例的qml封装成一个module
具体是在content/CMakeList.txt下,用qt6_add_qml_module去新建一个模块
然后去import这个模块,例如import titlebar 1.0 / import controlpanel 1.0这样
不过这个办法我也没有尝试过。
需要注意:调用时要加入
Component.onCompleted: {已经在多处都看见这种做法了
可能谈到调用就是异步的。
相关的帖子
Singletons in QML | Qt QML 6.7.2
Singleton QML failed to load as module
How to make a QML Component a Singleton?
Qt 创建 单例/Singleton qml 文件_pragma singleton-CSDN博客
004. QML中的signal & slot
要点:
- 1.信号要在本qml文件中的
顶层容器中进行定义 就算触发信号的位置是在本qml文件中嵌套的component里面,也都要在顶层容器中进行定义
rectangle{
...
signal Sig_Name_XXX
...
}
- 2.信号的使用必须加圆括号(),可以不必加分号;,否则会发不出去
signal Sig_Name_XXX()
- 3.信号的传递必须一层一层的传上去(若你是一层一层的封装好模块的话) 因为信号的接受者只能识别被它创建的那一个对象里面信号
container: Image
Property:
sourceSize.width:
sourceSize.height:
this property was used for recapture the source and made a new image internally. if image.width & image.height are illegal value(e.g,. 0), the sourceSize will have the original size of this picture.
005. enum Qt::WindowType & flags Qt::WindowFlags
// flags: Qt.Window | Qt.CustomizeWindowHint
// flags: Qt.Window | Qt.FramelessWindowHint | Qt.WindowMinimizeButtonHint | Qt.WindowMaximizeButtonHint
//设置无框的窗口
flags: Qt.Window | Qt.FramelessWindowHint
// flags: Qt.Window | Qt.CustomizeWindowHint | Qt.WindowTitleHint
enum Qt::WindowType flags Qt::WindowFlags
它的逻辑是首先判断是什么窗口类型,可选项有
1. Widget
2. Window
3. Dialog
4. Sheet
5. Drawer //outdated
6. Popup
7. Tool
8. ToolTip
9. SplashScreen
10. SubWindow
11. ForeignWindow
12. CoverWindow
所以这12种是所有的窗口类型
选择完我要的窗口Window,之后,我就可以进一步选择窗口标志
当然flag可是不止这两种,但是目前我就主要用到了这两种,所以其他的以后再补充啦哈哈
第一种就是无边框的窗体
第二种就是自定义的窗体
第二种接下来还有许多options是配合它出现的,也就是说,CustomizeWindowHint只是一个开关