文章简介

初学qml用来记录qml的学习过程,方便后面归纳总结整理。

1. 创建qml工程

如下图,我使用的是一个空的qml的工程,这样更容易上手。
qml和c++结合使用-LMLPHP

2. 创建一个类和qml文件,修改main函数

.h文件

#ifndef MYCPPOBJECT_H
#define MYCPPOBJECT_H

#include <QObject>

class MyCppObject : public QObject
{
    Q_OBJECT

public:
    MyCppObject(QObject *parent = nullptr);

signals:
    void sigButtonClick();

public slots:
    void handleButtonClick();
};

#endif // MYCPPOBJECT_H

cpp文件

#include "mycppobject.h"
#include <QDebug>
MyCppObject::MyCppObject(QObject *parent) : QObject(parent) {}

void MyCppObject::handleButtonClick()
{
    qDebug() << "click";
    // 处理按键点击事件
    // ...

    // 发出自定义信号
    emit sigButtonClick();
}

main函数

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    //注册自定义类
    qmlRegisterType<MyCppObject>("GenOsal", 0, 1, "MyCppObject");

    // 加载QML文件
    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/ButtonExample.qml")));
    // 在QML中注册自定义的C++类型
    if (engine.rootObjects().isEmpty())
    {
        return -1;
    }
    // 创建C++对象
    // MyCppObject myCppObject;
    // 将C++对象注册到QML引擎中
    // engine.rootContext()->setContextProperty("myCppObject", &myCppObject);
    return app.exec();
}

qml文件

// 写一个串口通信
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick.Controls 2.0

// 自定义的cpp(通过main.c注册进来)
import GenOsal 0.1

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("test Connect")

    // 用来连接cpp的信号
    Connections{
        target: m_object

        function onSigButtonClick(){
            console.log("recv button clicked");
        }
    }
    // 变量定义:var定义局部变量,只在当前QML文件中可用
    // property 定义对象属性的变量
    // let 定义常量,定义后不可以修改值
    Label{
        id: lab_com
        x: 0
        y: 0
        width: 120
        height: 50
        text: "端口号"
        color: "black"
        font.pixelSize: 18
        verticalAlignment: Text.AlignVCenter
        horizontalAlignment: Text.AlignHCenter
        background: Rectangle {
            implicitWidth: 100
            implicitHeight: 40
            color: "red"
            border.color: "#26282a"
            border.width: 1
            radius: 4
            gradient: Gradient{
                GradientStop { position: 0.0; color: mouseArea.pressed ?  "white" : "lightgray"}
                GradientStop { position: 1.0; color: mouseArea.pressed ?  "lightgray" : "gray"}
            }
        }
        MouseArea {
            id: mouseArea
            anchors.fill: parent
            onReleased: {
                // 直接调用函数
                m_object.handleButtonClick();
            }
            onPressed: {
            }
            onClicked: {
                console.log(edit_com.text);
            }
        }
    }

    Rectangle {
        // 设置部件的边距
        anchors.margins: {
            left:20
        }
        anchors.left: lab_com.right
        y: lab_com.y
        width: lab_com.width
        height: lab_com.height
        border.width: 1
        border.color: "gray"

        TextInput {
            id: edit_com
            anchors.fill: parent
            // enabled: bEnabled
            text: "0"
            visible: true
            font.pixelSize: 16
            focus: true
            horizontalAlignment: Text.AlignHCenter
            verticalAlignment: Text.AlignVCenter
            inputMethodHints: Qt.ImhDigitsOnly
            validator: IntValidator {top: 65535; bottom: 1}
            onFocusChanged: {
                // mainVKB.visible = true
            }
        }
    }
    MyCppObject{
        id: m_object
    }
}
3. 函数说明:
int qmlRegisterType(const char *uri, int versionMajor, int versionMinor, const char *qmlName);

参数说明:
通过调用qmlRegisterType函数,可以将自定义的C++类型注册到QML中,从而可以在QML代码中使用该类型。在注册成功后,可以在QML中通过该类型的名称来创建该类型的实例,并调用其属性和方法。
	uri:表示注册类型的命名空间,通常为项目的名称或者公司的域名,用于区分不同的QML模块。
	通常是import的内容:
	例如:
		qmlRegisterType<MySliderItem>("com.mycompany.qmlcomponents", 1, 0, "Slider");
		import com.mycompany.qmlcomponents 1.0
	versionMajor:主版本号,用于指定注册类型的版本信息。
	versionMinor:次版本号,用于指定注册类型的版本信息。
	qmlName:
		表示要注册的类型在QML中的名称,可以在QML中直接使用该名称来创建该类型的实例。
		首字母大写

C++注册方式2// 创建C++对象
MyCppObject myCppObject;
// 将C++对象注册到QML引擎中
engine.rootContext()->setContextProperty("myCppObject", &myCppObject);
4. qml 文件间的调用
命名:首字母大写
使用Load的方式调用问题较多,通常直接使用文件名来调用。
5. 界面布局

QML中布局一般有如下四种方式,

  1. 绝对坐标:x、y、z、width、height、
  2. 锚(anchors) 布局
  3. 定位器(Row、Column、Grid、Flow)
  4. 布局管理器(GridLayout、RowLayout、ColumnLayout)

锚布局:
这是一种相对位置关系的布局。特别说明margins是间距
qml和c++结合使用-LMLPHP定位器:
spacing: 2 //相邻间距
Repeater 重复布局

import QtQuick 2.0
Row
{
    Repeater 
    {
        model: 3
        Rectangle 
        {
            width: 100; height: 40
            border.width: 1
            color: "yellow"
        }
    }
}
Row 水平布局
Column 垂直布局
Grid
Flow
布局管理器: 和Creator中一样

cpp中的函数
void MyCppObject::handleButtonClick()
{
    qDebug() << "click";
    // 处理按键点击事件
    // ...

    // 发出自定义信号
    emit sigButtonClick();
}

public slots:
    void handleButtonClick();
6. 代码举例

Label

 Label{
	property bool bEnable: false
	property int nIndex: 1
	signal effective()
	signal clicksignal()
	
	id: lab_com
	x: 0
	y: 0
	width: 120
	height: 50
	text: "端口号"
	color: "black"
	font.pixelSize: 18
	verticalAlignment: Text.AlignVCenter
	horizontalAlignment: Text.AlignHCenter

	background: Rectangle {
	    implicitWidth: 100
	    implicitHeight: 40
	    color: "red"
	    border.color: "#26282a"
	    border.width: 1
	    radius: 4
	    gradient: Gradient{//颜色渐变
	        GradientStop { position: 0.0; color: mouseArea.pressed ?  "white" : "lightgray"}
	        GradientStop { position: 1.0; color: mouseArea.pressed ?  "lightgray" : "gray"}
	    }
	}
	MouseArea {
	    id: mouseArea
	    anchors.fill: parent
	    onReleased: {
	        bEnable = false
	        effective()
	    }
	    onClicked: {
	        clicksignal()
	    }
	}
}

Textinput

    Rectangle {
        width: 178
        height: parent.height
        color: bEnabled? "white" : "lightgray"
        border.width: 1
        border.color: "gray"

        TextInput {
            id: textData
            anchors.fill: parent
            enabled: bEnabled
            text: "0"
            visible: true
            font.pixelSize: 16
            focus: true
            horizontalAlignment: Text.AlignHCenter
            verticalAlignment: Text.AlignVCenter
            inputMethodHints: Qt.ImhDigitsOnly
            validator: IntValidator {top: 65535; bottom: 1}
            onFocusChanged: {
                mainVKB.visible = true
            }
        }
    }
Text
Text {
     width: 100
     height: 15
     text: sLableDown
     font.pixelSize: 14
     font.bold: true
     color: "black"
     horizontalAlignment: Text.AlignHCenter
     verticalAlignment: Text.AlignVCenter
 }
04-30 18:11