前言
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) 布局的参数:
//左上右下对齐
anchors.left : AnchorLine
anchors.top : AnchorLine
anchors.right : AnchorLine
anchors.bottom : AnchorLine
//Margin
anchors.leftMargin : real
anchors.topMargin : real
anchors.rightMargin : real
anchors.bottomMargin : real
anchors.margins : real
//基线对齐及偏移
anchors.baseline : AnchorLine
anchors.baselineOffset : real
anchors.mirrored : bool
anchors.fill : Item
//居中与偏移
anchors.centerIn : Item
anchors.horizontalCenter : AnchorLine
anchors.verticalCenter : AnchorLine
anchors.horizontalCenterOffset : real
anchors.verticalCenterOffset : real
其中
- real 具体的数值
- Item是组建的ID或者parent
- bool是true或false
- AnchorLine 示例
anchors.horizontalCenter: parent.horizontalCenter
注意
不要在Row或RowLayout相关的组件中使用anchors,会导致组件本身的特性不生效。
窗口设置
窗口的属性
Window {
title: qsTr("一个普通标题窗口") //窗口标题
width: 640 //宽度
height: 480 //高度
visible: true //是否可见,缺省为true
color: "#ffffff" //窗口背景色
//#00000000 为窗口透明
//QML支持black 等颜色样式(没有#)
//QML支持#11cfff 等颜色样式
//QML同样支持RGB格式
flags: Qt.Window //窗口标志 说明是什么窗口 使用 | 分割,缺省为Qt.Window
//Qt.Window 普通窗口模式,带标题栏
//Qt.FramelessWindowHint 隐藏标题栏窗口
opacity: 1 //透明度 数值区间为0~1 支持小数,缺省为1
x:0 //位于父窗体的x位置,以左上角为起点,缺省为0 (此时window的父窗体就是桌面了)
y:0 //位于父窗体的y位置,以左上角为起点,缺省为0 (此时window的父窗体就是桌面了)
}
无边框
Window {
width: 640
height: 480
visible: true
color: "#fefefe"
title: qsTr("主页面")
flags: "FramelessWindowHint"
}
显示标题栏,但是没有关闭最大最小化按钮
Window {
width: 640
height: 480
visible: true
color: "#fefefe"
title: qsTr("主页面")
flags: "CustomizeWindowHint"
}
背景透明无边框窗口
Window {
width: 640
height: 480
visible: true
color: "#00000000"
title: qsTr("主页面")
flags: Qt.FramelessWindowHint
opacity:1
}
opacity这个属性是对当前组件以及子组件都设置不透明度,所以不太适用
color: Qt.rgba(0,0,0,0)
是对当前设置透明度,不会传到子组件
组件
基本组件
这里面的这几个内部也可以填充其它组件
- MouseArea
- Rectangle
定位组件和布局管理器
定位器(Row、Column、Grid、Flow)
布局管理器(RowLayout、ColumnLayout、GridLayout、StackLayout)
Layout
要使用layout布局的属性 需要引用
import QtQuick.Layouts 1.12
示例1
一个简单的示例
横向分布,最后一个填充剩余空间。
import QtQuick 2.14
import QtQuick.Window 2.14
import QtQuick.Layouts 1.12
Window {
width: 640
height: 480
visible: true
color: "#f3f3f3"
title: qsTr("主页面")
RowLayout {
id: row
height: 200
spacing: 0
anchors.left:parent.left
anchors.right:parent.right
Rectangle {
id: rectangle
width: 200
height: parent.height
color: "red"
}
Rectangle {
id: rectangle2
width: 200
height: parent.height
color: "green"
}
Rectangle {
id: rectangle3
height: parent.height
color: "blue"
Layout.fillWidth: true
}
}
}
显示效果
其中
RowLayout {
id: row
height: 200
spacing: 0
anchors.left:parent.left
anchors.right:parent.right
}
和
RowLayout {
id: row
height: 200
width:parent.width
spacing: 0
}
是等效的,前者就用了锚(anchors) 布局
只有在Layout相关的空间中才能使用Layout.fillWidth: true
相关的属性。
所以RowLayout
可以实现元素填充剩余空间,而Row
是不可以的,除非我们复制宽度是通过计算的值。
代码如下
import QtQuick 2.14
import QtQuick.Window 2.14
import QtQuick.Layouts 1.12
Window {
width: 640
height: 480
visible: true
color: "#f3f3f3"
title: qsTr("主页面")
Row {
id: row
height: 200
spacing: 0
anchors.left:parent.left
anchors.right:parent.right
Rectangle {
id: rectangle
width: 200
height: parent.height
color: "red"
}
Rectangle {
id: rectangle2
width: 200
height: parent.height
color: "green"
}
Rectangle {
id: rectangle3
height: parent.height
width: parent.width-rectangle.width-rectangle2.width
color: "blue"
}
}
}
示例2
基本的事件和按钮按压变色及点击事件
import QtQuick 2.14
import QtQuick.Window 2.14
import QtQuick.Layouts 1.12
Window {
width: 640
height: 480
visible: true
color: "#f3f3f3"
title: qsTr("主页面")
MouseArea {
width: 200
height: 200
anchors.centerIn: parent
Rectangle {
id:myrect
anchors.fill: parent
color: "blue"
Text {
text: "点击"
color: "white"
font.pixelSize: 16
anchors.centerIn: parent
}
}
onClicked: {
console.log("区域点击")
}
onPressedChanged: {
if(pressed){
myrect.color="green"
}else{
myrect.color="blue"
}
console.log(pressed)
}
}
Component.onCompleted: {
console.log("加载完毕")
}
}
Rectangle的事件
Rectangle {
width: 600
height: 400
anchors.centerIn: parent
color: "lightgray"
TapHandler {
//点击屏幕时,修改了pressed属性,触发onPressedChanged
onPressedChanged: {
console.log("press ? : ", pressed)
}
//长按时触发onLongPressed
onLongPressed: {
console.log("long pressed")
}
}
}
QML 信号与槽
方式1
对于 QML 中的属性如果其值发生改变, QML 自动会发生相关信号
on<Property>Changed
这种格式
举例:
MouseArea {
onPressedChanged: console.log("value:" , pressed)
}
方式2
比较适合在同一个 QML 文件内
signal <name> (type parameter, type parameter)
on<Name>
例如:
signal testSignal(real x, real b)
testSignal(x, b) //执行 也就是 发送信号 类似 quick 中的 emit signal()
onTestSignal: console.log("xxx")// 槽 用于接收信号
举例:
Item {
signal clickTest();
MouseArea {
onPressed: {
clickTest()
}
}
onClickTest: consloe.log("received")
}
方式3
适合一对多或者跨 QML 断开就使用 disconnect 就好
1 : 跟信号在同一个范围,可这么写
signal sendSignal();
MouseArea {
sendSignal()
}
Component.onCompleted: {
sendSignal.connect(send21)
sendSignal.connect(send22)
sendSignal.connect(send23)
}
function send21() {
console.log("1: received signal");
}
function send22() {
console.log("2: received signal");
}
function send23() {
console.log("3: received signal");
}
2:如果与信号不在同一范围
MyTest {
signal testT()
id : mytest
MouseArea {
onPressed: {
mytest.testT()
}
}
}
Component.onCompleted: {
mytest.testT.connect(send21) // mytest.testT.disconnect(send21)
mytest.testT.connect(send22)
mytest.testT.connect(send23)
}
function send21() {
console.log("1: received signal");
}
function send22() {
console.log("2: received signal");
}
function send23() {
console.log("3: received signal");
}
3、Connections 最主要的优势可以连接到没有定义在 QML 的东西 格式:
Connections {
target: 信号的来源
on<Signal>:
}
Connections {
target: mytest
onTestT: {
send21();
}
}