前言
QT文档:https://runebook.dev/zh-CN/docs/qt/
QT Quick
和Qt widgets
这两种技术,官方是强推QT Quick
的。
定位
QT Quick中布局一般有如下四种方式,
- 绝对坐标:x、y、z、width、height、top、left
- 锚(anchors) 布局
- 定位器(Row、Column、Grid、Flow)
- 布局管理器(RowLayout、ColumnLayout、GridLayout、StackLayout)
绝对布局很好理解,给值就显示,但是不灵活;
anchors 实际上是 Item 的一个属性集
Row 则是一个单独的 Item ,专门用来管理其它 Item 的,后面介绍的几种布局,也是类似的。
锚(anchors) 布局的参数:
1 | //左上右下对齐 |
其中
- real 具体的数值
- Item是组建的ID或者parent
- bool是true或false
- AnchorLine 示例
anchors.horizontalCenter: parent.horizontalCenter
注意
不要在Row或RowLayout相关的组件中使用anchors,会导致组件本身的特性不生效。
窗口设置
窗口的属性
1 | Window { |
无边框
1 | Window { |
显示标题栏,但是没有关闭最大最小化按钮
1 | Window { |
背景透明无边框窗口
1 | Window { |
opacity这个属性是对当前组件以及子组件都设置不透明度,所以不太适用
color: Qt.rgba(0,0,0,0)
是对当前设置透明度,不会影响子组件
注意
Qt.FramelessWindowHint
无边框Qt.Window
显示在状态栏Qt.WindowStaysOnTopHint
窗口置顶
窗口穿透
局部穿透
https://doc.qt.io/qt-5/qwindow.html#setMask
官网是这么说的
The mask is a hint to the windowing system that the application does not want to receive mouse or touch input outside the given region.
意思是
应用不接收给定的区域之外的事件。
工具类
1 | from PySide2 import QtCore |
布局
1 | import QtQuick 2.14 |
程序入口
1 | import sys |
注意
这样其实窗口背景不是透明的也没关系,因为这个方法相当于把穿透的地方都裁剪掉了。
注意上面的例子中传入的坐标区域是不穿透的,
如果想要传入的地方穿透
1
2
3 >fillscreen = window.screen().geometry()
> region = region.xored(fillscreen)
>
把选择的区域反向就行了。
整体穿透
如果整体穿透直接用flags属性设置就行了
1 | Window { |
主要是这个属性Qt.WindowTransparentForInput
窗口拖动/菜单/托盘
1 | import QtQuick 2.9 |
组件
基本组件
这里面的这几个内部也可以填充其它组件
- FocusScope
- MouseArea
- Rectangle
Text/TextInput/TextEdit
Text 只支持文本的显示。
TextInput 编辑一行文本。
TextEdit 提供的多行文本编辑框。
Image/AnimatedImage/BorderImage
Image用来展示静态图片
1 | Image { |
AnimatedImage展示动态图片
AnimatedImage 提供了五个属性:
- currentFrame,指示当前正在播放的帧序号
- frameCount,指示图片的总帧数
- paused,表示是否暂停,设置它也可以暂停或继续播放
- playing,指示动画是否在播放,默认为 true ,意思是 AnimatedImage 对象创建后立即开始播放
- source,类型为 url ,指定要播放的图片地址,可以使本地文件、 qrc 里的资源、网络文件
示例
1 | AnimatedImage { |
BorderImage 能设置圆角的组件
1 | BorderImage { |
Rectangle
填充渐变色
1 | Rectangle { |
Item
Item 类型比较特殊,因为它是所有其他可视化类型的基类型。
尽管一个 Item 对象本身没有一个可视化的外观,但是它定义了可视化项目中所有常见的特性,比如 x 、y 、width 、height 、anchors 和键盘处理等。Item 类型最常见的用法是作为其他项目的容器,这样就可以把其他项目作为一个整体.
1 | Item { |
MouseArea
工具类组件,没有外观。
MouseArea的作用是监听点击方法。
1 | MouseArea |
MouseArea子对象是鼠标区域,是一个不可见的组件,通过MouseArea对象可以实现鼠标互动。将鼠标区域覆盖整个Rectangle窗口。
开启事件传递
MouseArea 有一个属性为 propagateComposedEvents
,默认为 false,当设置为 true 时,就可以将事件传递给重叠的其他鼠标区域了(包括控件),见 Qt 官方文档:https://doc.qt.io/qt-5/qml-qtquick-mousearea.html#propagateComposedEvents-prop,示例代码如下:
1 | MouseArea { |
以上代码中开启了 propagateComposedEvents
属性,并且将 onClicked
中 mouse.accepted
重置为 false 了,这样 onClicked 事件就会顺利的传递到下层控件中。如果你希望所有点击和释放操作都传递到下层,可以将 onPressed、onReleased 都重写掉,设置 accepted 为 false,如下示例:
1 | MouseArea { |
这样实现后,这个 MouseArea 的所有点击、按下、释放操作都会传递到下层,而且如果你开启了 hoverEnabled
属性,还不影响 onPositionChanged
(鼠标移动)的事件响应,完美的实现了一个鼠标区域只响应鼠标移动但又可以传递点击等事件到下层控件的需求。
FocusScope
FocusScope继承Item,是一个工具类组件,没有外观,一般都作为root组件出现。
QML中事件的传递顺序是 从外而内,从下而上
,这个顺序是和qml内部组件实例化顺序一致的。
1 | Rectangle{ |
Flipable
一个工具类组件,没有外观
Flipable 是一种可以在其正面和背面之间明显“翻转”的物品,就像卡片一样。它可以与Rotation、State和Transition类型一起使用以产生翻转效果。
front
和back
属性被用来容纳被分别显示在flipable项目的正面和背面上的项目。
1 | Flipable { |
定位组件和布局管理器
定位器(Row、Column、Grid、Flow)
布局管理器(RowLayout、ColumnLayout、GridLayout、StackLayout)
Layout
要使用layout布局的属性 需要引用
1 | import QtQuick.Layouts 1.12 |
示例1
一个简单的示例
横向分布,最后一个填充剩余空间。
1 | import QtQuick 2.14 |
显示效果
其中
1 | RowLayout { |
和
1 | RowLayout { |
是等效的,前者就用了锚(anchors) 布局
只有在Layout相关的控件中才能使用Layout.fillWidth: true
相关的属性。
所以RowLayout
可以实现元素填充剩余空间,而Row
是不可以的,除非我们复制宽度是通过计算的值。
代码如下
1 | import QtQuick 2.14 |
示例2
基本的事件和按钮按压变色及点击事件
1 | import QtQuick 2.14 |
Rectangle的事件
1 | Rectangle { |
QML 信号与槽
方式1
对于 QML 中的属性如果其值发生改变, QML 自动会发生相关信号
on<Property>Changed
这种格式
举例:
1 | MouseArea { |
方式2
比较适合在同一个 QML 文件内
1 | signal <name> (type parameter, type parameter) |
例如:
1 | signal testSignal(real x, real b) |
举例:
1 | Item { |
方式3
适合一对多或者跨 QML
断开就使用 disconnect 就好
1 : 跟信号在同一个范围,可这么写
1 | signal sendSignal(); |
2:如果与信号不在同一范围
1 | MyTest { |
3:Connections 最主要的优势可以连接到没有定义在 QML 的东西
格式:
1 | Connections { |
示例1
2
3
4
5
6Connections {
target: mytest
onTestT: {
send21();
}
}
QML中调用Python的函数
main.qml
1 | import QtQuick 2.14 |
main.py
1 | import os |
Python 连接 QML 信号
(QML 发信号, Python 为槽)
main.qml
1 | import QtQuick 2.14 |
main.py
1 | import sys |
Python获取控件
1 | Text { |
获取控件
1 | txt_obj = engine.rootObjects()[0].findChild(QObject, "mytext") |
获取控件属性的值:
1 | txt_value = txt_obj.property("text") |
设置控件属性的值:
1 | txt_obj.setProperty("text", "Clicked!") |