qml嵌入

原文地址 zhuanlan.zhihu.com

qt-qml

残枫cps残枫cps

​目录收起QWidget嵌入Qml文件第一种 QQmlApplicationEngine第二种 QQuickView第三种 QQuickWidgetQML 是一种基于 JavaScript 的声明式语言qml属性qml定位器 :Row、Column、Grid和Flow锚点(anchor)输入元素Repeater 动态视图 ListView和GridView 即滚动列表视图代理模型-视图高级技术 PathView从 XML 加载模型分组列表Canvas粒子系统

QWidget嵌入Qml文件

第一种 QQmlApplicationEngine

QQmlApplicationEngine engine;

engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

1

2

其中main.qml 可以以Window作为根元素,这个时候QML就完全拥有了控制权,可以直接设置窗体的标题、尺寸等信息;

第二种 QQuickView

QQuickView最常见的用法如下:

QQuickView view;

view.setResizeMode (QQuickView::SizeRootObjectToView);

view.setSource (QUrl("qrc:/main.qml"));

view.show ();

注意:其中qml文件不能以Window作为根元素,最佳选择是使用Item为根元素,否则会警告:

QQuickView does not support using windows as a root item.

If you wish to create your root window from QML, consider using QQmlApplicationEngine instead.

第三种 QQuickWidget

官网自带的说明例子.一般用来在QWidget界面上加载QML界面

QQuickWidget *view = new QQuickWidget;

view->setSource(QUrl::fromLocalFile("myqmlfile.qml"));

view->show();

QML 是一种基于 JavaScript 的声明式语言

QML 文档描述了一个对象树。QML 元素包含了其构造块、图形元素(矩形、图片等)和行为(例如动画、切换等)。这些 QML 元素按照一定的嵌套关系构成复杂的组件,供用户交互。

Qt Quick 就是使用 QML 构建的一套类库。

一个 QML 文档分为 import 和对象声明两部分。如果你要使用 Qt Quick,就需要 import QtQuick 2。QML 是一种声明语言,用于描述程序界面。QML 将用户界面分解成一块块小的元素,每一元素都由很多组件构成。QML 定义了用户界面元素的外观和行为;更复杂的逻辑则可以结合 JavaScript 脚本实现。这有点类似于 HTML 和 JavaScript 的关系,前者用来显示界面,后者用来定义行为。

  1. // rectangle.qml
  2. import QtQuick 2.0
  3. // 根元素:Rectangle
  4. Rectangle {
  5. // 命名根元素
  6. id: root // 声明属性::
  7. width: 120; height: 240
  8. color: "#D8D8D8" // 颜色属性
  9. // 声明一个嵌套元素(根元素的子元素)
  10. Image {
  11. id: rocket
  12. x: (parent.width - width)/2; y: 40 // 使用 parent 引用父元素
  13. source: 'assets/rocket.png'
  14. }
  15. // 根元素的另一个子元素
  16. Text {
  17. // 该元素未命名
  18. y: rocket.y + rocket.height + 20 // 使用 id 引用元素
  19. width: root.width // 使用 id 引用元素
  20. horizontalAlignment: Text.AlignHCenter
  21. text: 'Rocket'
  22. }
  23. }
  24. Text {
  25. // (1) 标识符
  26. id: thisLabel
  27. // (2) x、y 坐标
  28. x: 24; y: 16
  29. // (3) 绑定
  30. height: 2 * width
  31. // (4) 自定义属性
  32. property int times: 24
  33. // (5) 属性别名
  34. property alias anotherTimes: times
  35. // (6) 文本和值
  36. text: "Greetings " + times
  37. // (7) 字体属性组
  38. font.family: "Ubuntu"
  39. font.pixelSize: 24
  40. // (8) 附加属性 KeyNavigation
  41. KeyNavigation.tab: otherLabel
  42. // (9) 属性值改变的信号处理回调
  43. onHeightChanged: console.log('height:', height)
  44. // 接收键盘事件需要设置 focus
  45. focus: true
  46. // 根据 focus 值改变颜色
  47. color: focus?"red":"black"
  48. }
  49. Text {
  50. id: label
  51. x: 24; y: 24
  52. // 自定义属性,表示空格按下的次数
  53. property int spacePresses: 0
  54. text: "Space pressed: " + spacePresses + " times"
  55. // (1) 文本变化的响应函数
  56. onTextChanged: console.log("text changed to:", text)
  57. // 接收键盘事件,需要设置 focus 属性
  58. focus: true
  59. // (2) 调用 JavaScript 函数
  60. Keys.onSpacePressed: {
  61. increment()
  62. }
  63. // 按下 Esc 键清空文本
  64. Keys.onEscapePressed: {
  65. label.text = ''
  66. }
  67. // (3) 一个 JavaScript 函数
  68. function increment() {
  69. spacePresses = spacePresses + 1
  70. }
  71. }

qml属性

QML 基本元素可以分为可视元素和不可视元素两类。可视元素(例如前面提到过的Rectangle)具有几何坐标,会在屏幕上占据一块显示区域。不可视元素(例如Timer)通常提供一种功能,这些功能可以作用于可视元素。

本章我们将会集中介绍集中最基本的可视元素:Item、Rectangle、Text、Image和MouseArea。

Item是所有可视元素中最基本的一个。它是所有其它可视元素的父元素,可以说是所有其它可视元素都继承Item。Item本身没有任何绘制,它的作用是定义所有可视元素的通用属性:

前面我们说过,Item定义了所有可视元素都具有的属性。所以在下面的内容中,我们会再次详细介绍这些属性。

除了定义通用属性,Item另外一个重要作用是作为其它可视元素的容器。从这一点来说,Item非常类似于 HTML 中 div 标签的作用。

MouseArea。顾名思义,这个元素用于用户交互。这是一个不可见的矩形区域,用于捕获鼠标事件。

MouseArea是 QtQuick 的重要组成部分,它将可视化展示与用户输入控制解耦。通过这种技术,你可以显示一个较小的元素,但是它有一个很大的可交互区域,以便在界面显示与用户交互之间找到一个平衡(如果在移动设备上,较小的区域非常不容易被用户成功点击。苹果公司要求界面的交互部分最少要有 40 像素以上,才能够很容易被手指点中)。

自定义组件:文件名首字母大写(不然在使用中会报没有这个属性错误);在pro文件中声明。

qml定位器 :Row、Column、Grid和Flow

https://www.bookstack.cn/read/qt-study-road-2/845b0afc468e33c4.md

QML 提供了很多用于定位的元素。这些元素叫做定位器,都包含在 QtQuick 模块。这些定位器主要有 Row、Column、Grid和Flow等

Repeater非常像一个for循环,它能够遍历数据模型中的元素。

锚点(anchor)

https://www.bookstack.cn/read/qt-study-road-2/f15a21344cfbabd8.md

锚点允许我们灵活地设置两个元素的相对位置。它使两个元素之间形成一种类似于锚的关系,也就是两个元素之间形成一个固定点。锚点的行为类似于一种链接,它要比单纯地计算坐标改变更强。由于锚点描述的是相对位置,所以在使用锚点时,我们必须指定两个元素,声明其中一个元素相对于另外一个元素。锚点是Item元素的基本属性之一,因而适用于所有 QML 可视元素。

一个元素有 6 个主要的锚点的定位线,如下图所示:

这 6 个定位线分别是:top、bottom、left、right、horizontalCenter和verticalCenter。对于Text元素,还有一个baseline锚点。每一个锚点定位线都可以结合一个偏移的数值。其中,top、bottom、left和right称为外边框;horizontalCenter、verticalCenter和baseline称为偏移量。

输入元素

TextInput是单行的文本输入框,支持验证器、输入掩码和显示模式等。

KeyNavigation是一个附加属性。当用户点击了指定的按键时,属性指定的组件就会获得焦点。附加属性类似于普通属性,但是又有所区别。普通的属性隶属于这个类型;附加属性一般用于修饰或补充目标类型。比如这里的http://KeyNavigation.tab并不是TextInput的普通属性,仅仅是用来说明TextInput的一种特征。附加属性的一般语法是类型.属性名,以此为例,类型就是KeyNavigation,属性名就是tab。

  1. import QtQuick 2.0
  2. Rectangle {
  3. width: 200
  4. height: 80
  5. color: "linen"
  6. TextInput {
  7. id: input1
  8. x: 8; y: 8
  9. width: 96; height: 20
  10. focus: true
  11. text: "Text Input 1"
  12. KeyNavigation.tab: input2
  13. }
  14. TextInput {
  15. id: input2
  16. x: 8; y: 36
  17. width: 96; height: 20
  18. text: "Text Input 2"
  19. KeyNavigation.tab: input1
  20. }
  21. }
    为了让外界可以直接设置TextInput的text属性,我们给这个属性声明了一个别名。同时,为了让外界可以访问到内部的textInput,我们将这个子组件也暴露出来。不过,从封装的角度而言,将实现细节暴露出去并不是一个好的设计,这要看暴露出来这个子组件的影响究竟有多大。
  22. // LineEdit.qml
  23. import QtQuick 2.0
  24. Rectangle {
  25. width: 96;
  26. height: input.height + 8
  27. color: "lightsteelblue"
  28. border.color: "gray"
  29. property alias text: input.text
  30. property alias input: input
  31. TextInput {
  32. id: input
  33. anchors.fill: parent
  34. anchors.margins: 4
  35. focus: true
  36. }
  37. }

FocusScope接收到焦点时,会将焦点转发给最后一个设置了focus:true的子对象

  1. FocusScope {
  2. width: 96;
  3. height: input.height + 8
  4. color: "lightsteelblue"
  5. border.color: "gray"
  6. property alias text: input.text
  7. property alias input: input
  8. TextInput {
  9. id: input
  10. anchors.fill: parent
  11. anchors.margins: 4
  12. focus: true
  13. }
  14. }

TextEdit是多行的文本编辑组件

附加属性Keys类似于键盘事件,允许我们相应特定的按键按下事件。例如,我们可以利用方向键控制举行的位置,如下代码所示:

  1. import QtQuick 2.0
  2. DarkSquare {
  3. width: 400; height: 200
  4. GreenSquare {
  5. id: square
  6. x: 8; y: 8
  7. }
  8. focus: true
  9. Keys.onLeftPressed: square.x -= 8
  10. Keys.onRightPressed: square.x += 8
  11. Keys.onUpPressed: square.y -= 8
  12. Keys.onDownPressed: square.y += 8
  13. Keys.onPressed: {
  14. switch(event.key) {
  15. case Qt.Key_Plus:
  16. square.scale += 0.2
  17. break;
  18. case Qt.Key_Minus:
  19. square.scale -= 0.2
  20. break;
  21. }
  22. }
  23. }

Qt Quick Controls。

顾名思义,这个模块提供了大量类似 Qt Widgets 模块那样可重用的组件。本章我们将介绍 Qt Quick Controls,你会发现这个模块与 Qt 组件非常类似。

应用程序窗口
用于描述应用程序的基本窗口属性的组件
ApplicationWindow对应QMainWindow,提供顶层应用程序窗口
MenuBar对应QMenuBar,提供窗口顶部横向的菜单栏
StatusBar对应QStatusBar,提供状态栏
ToolBar对应QToolBar,提供工具栏,可以添加ToolButton和其它组件
Action对应QAction,提供能够绑定到导航和视图的抽象的用户界面动作
导航和视图
方便用户在一个布局中管理和显示其它组件
ScrollView对应QScrollView,提供滚动视图
SplitView对应QSplitter,提供可拖动的分割视图布局
StackView对应QStackedWidget,提供基于栈的层叠布局
TabView对应QTabWidget,提供带有标签的基于栈的层叠布局
TableView对应QTableWidget,提供带有滚动条、样式和表头的表格
控件
控件用于表现或接受用户输入
BusyIndicator提供忙等示意组件
Button对应QPushButton,提供按钮组件
CheckBox对应QCheckBox,提供复选框
ComboBox对应QComboBox,提供下拉框
GroupBox对应QGroupBox,提供带有标题、边框的容器
Label对应QLabel,提供标签组件
ProgressBar对应QProgressBar,提供进度条组件
RadioButton对应QRadioButton,提供单选按钮
Slider对应QSlider,提供滑动组件
SpinBox对应QSpinBox,提供微调组件
Switch提供类似单选按钮的开关组件
TextArea对应QTextEdit,提供能够显示多行文本的富文本编辑框
TextField对应QTextLine,提供显示单行文本的纯文本编辑框
ToolButton对应QToolButton,提供在工具栏上显示的工具按钮
ExclusiveGroup提供互斥
菜单
用于构建菜单的组件
Menu对应QMenu,提供菜单、子菜单、弹出菜单等
MenuSeparator提供菜单分隔符
MenuItem提供添加到菜单栏或菜单的菜单项
StatusBar对应QStatusBar,提供状态栏
ToolBar对应QToolBar,提供工具栏,可以添加ToolButton和其它组件

Repeater

能够使用 JavaScript 数组作为Repeater的模型,而 JavaScript 数组能够以对象作为其元素类型,因而Repeater就可以处理复杂的数据项,比如带有属性的对象。这种情况其实更为常见。相比普通的 JavaScript 对象,更常用的是ListElement类型。类似普通 JavaScript 对象,每一个ListElement可以有任意属性。例如下面的代码示例中,每一个数据项都有一个名字和外观颜色。

  1. import QtQuick 2.2
  2. Column {
  3. spacing: 2
  4. Repeater {
  5. model: ListModel {
  6. ListElement
  7. ListElement
  8. ListElement
  9. ListElement
  10. ListElement
  11. ListElement
  12. ListElement
  13. ListElement
  14. }
  15. Rectangle {
  16. width: 100
  17. height: 20
  18. radius: 3
  19. color: "lightBlue"
  20. Text {
  21. anchors.centerIn: parent
  22. text: name
  23. }
  24. Rectangle {
  25. anchors.left: parent.left
  26. anchors.verticalCenter: parent.verticalCenter
  27. anchors.leftMargin: 2
  28. width: 16
  29. height: 16
  30. radius: 8
  31. border.color: "black"
  32. border.width: 1
  33. color: surfaceColor
  34. }
  35. }
  36. }
  37. }

运行结果如下图所示:

ListElement的每个属性都被Repeater绑定到实例化的显示项。正如上面代码中显示的那样,这意味着每一个用于显示数据的Rectangle作用域内都可以访问到ListElement的name和surfaceColor属性。

动态视图 ListView和GridView 即滚动列表

Repeater适用于少量的静态数据集。但是在实际应用中,数据模型往往是非常复杂的,并且数量巨大。这种情况下,Repeater并不十分适合。于是,QtQuick 提供了两个专门的视图元素:ListView和GridView。这两个元素都继承自Flickable,因此允许用户在一个很大的数据集中进行移动。同时,ListView和GridView能够复用创建的代理,这意味着,ListView和GridView不需要为每一个数据创建一个单独的代理。这种技术减少了大量代理的创建造成的内存问题。

视图代理

Qt model/view 架构类似,在自定义用户界面中,代理扮演着重要的角色。模型中的每一个数据项都要通过一个代理向用户展示,事实上,用户看到的可视部分就是代理。

每一个代理都可以访问一系列属性和附加属性。这些属性及附加属性中,有些来自于数据模型,有些则来自于视图。前者为代理提供了每一个数据项的数据信息;后者则是有关视图的状态信息。

代理中最常用到的是来自于视图的附加属性ListView.isCurrentItem和ListView.view。前者是一个布尔值,用于表示代理所代表的数据项是不是视图所展示的当前数据项;后者则是一个只读属性,表示该代理所属于的视图。通过访问视图的相关数据,我们就可以创建通用的可复用的代理,用于适配视图的大小和展示特性。下面的例子展示了每一个代理的宽度都绑定到视图的宽度,而代理的背景色则根据附加属性ListView.isCurrentItem的不同而有所不同。

  1. import QtQuick 2.0
  2. Rectangle {
  3. width: 120
  4. height: 300
  5. gradient: Gradient {
  6. GradientStop
  7. GradientStop
  8. }
  9. ListView {
  10. anchors.fill: parent
  11. anchors.margins: 20
  12. clip: true
  13. model: 100
  14. delegate: numberDelegate
  15. spacing: 5
  16. focus: true
  17. }
  18. Component {
  19. id: numberDelegate
  20. Rectangle {
  21. width: ListView.view.width
  22. height: 40
  23. color: ListView.isCurrentItem?"#157efb":"#53d769"
  24. border.color: Qt.lighter(color, 1.1)
  25. Text {
  26. anchors.centerIn: parent
  27. font.pixelSize: 10
  28. text: index
  29. }
  30. }
  31. }
  32. }

模型-视图高级技术

PathView

从 XML 加载模型

分组列表

https://www.bookstack.cn/read/qt-study-road-2/340ee79fddc2d44f.md

Canvas

https://www.bookstack.cn/read/qt-study-road-2/01ab6cd4ed7ab721.md

粒子系统

https://www.bookstack.cn/read/qt-study-road-2/de0c9d561eb0f5eb.md

发布于 2023-04-14 15:17・IP 属地山东开启赞赏赞赏开启后,读者将可以付费支持你的创作。Qt Quick​赞同​添加评论​分享​喜欢​收藏​设置赞同​分享

posted @ 2023-04-13 17:57  cps666  阅读(132)  评论(0编辑  收藏  举报