【QT Quick】函数与信号处理:QML函数定义与调用

本节课讲解了如何在 QML 6 中定义和调用函数,探讨了函数与属性、JS 函数的关系,以及它们在不同场景中的使用方法。我们将按照以下内容展开详细教程:

QML 函数基本特征

  • QML 6 中函数作为属性的一部分存在,类似 C++ 的成员函数。
  • 函数可以包含参数和返回值,但这些都是可选的。
  • QML 6 和 JS 函数互相兼容,但 JS 函数不支持 QML 类型,因此当函数调用跨到 JS 层时,通常使用 var 类型或不指定类型。

QML 6 函数定义格式

  • 函数的名称必须以小写字母开头,符合语法格式要求。

  • 可以定义参数类型和返回值类型,格式如下:

    qml 复制代码
    function 函数名(参数1: 参数类型, 参数2: 参数类型): 返回值类型 {
        // 函数体
        return 返回值;
    }

与 JS 函数的区别

  • JS 函数灵活,但没有强类型检查,而 QML 函数可以指定类型。
  • JS 函数与 QML 函数通过 import 模块互相调用。QML 通过 ID 来访问不同层次的函数,JS 则通过模块名访问。

函数调用的两种方式

  • 直接调用:通过 ID 或当前作用域直接调用。
  • 作为属性赋值:QML 属性可以赋值为一个函数,返回值将影响属性值。

函数指针与回调机制

  • QML 6 中函数也可作为变量传递,类似 C++ 中的函数指针。此特性允许实现回调机制,用于动态重构函数逻辑。

示例代码讲解

定义简单函数

我们首先在 QML 中定义一个简单函数:

qml 复制代码
import QtQuick
import QtQuick.Controls

Rectangle {
    width: 200
    height: 100
    id: root
    
    function testFunction(index: int, str: string): int {
        console.log("Called with index:", index, "and str:", str)
        return 1001
    }
    
    Button {
        text: "Call Function"
        anchors.centerIn: parent
        onClicked: {
            let result = root.testFunction(99, "Hello")
            console.log("Function returned:", result)
        }
    }
}

调用与返回值

  • 在按钮点击时调用函数 testFunction,并传递参数 99"Hello"
  • 输出函数返回的值 1001
qml 复制代码
Button {
    text: "Call Function"
    onClicked: {
        let result = root.testFunction(99, "Hello")
        console.log("Function returned:", result)
    }
}

使用 JS 文件定义函数

可以将函数定义在独立的 JS 文件中,并通过 QML 调用:

  1. 在 QML 中引入 JS 文件:

    qml 复制代码
    import "myFunctions.js" as MyFunctions
  2. myFunctions.js 中定义函数:

    javascript 复制代码
    function externalFunction(arg) {
        console.log("External function called with arg:", arg)
        return arg.length
    }
  3. 调用方式:

    qml 复制代码
    onClicked: {
        let length = MyFunctions.externalFunction("Hello from JS")
        console.log("Length returned:", length)
    }

通过属性调用函数

我们可以将属性赋值为一个函数,从而动态决定属性值:

qml 复制代码
Text {
    text: getTitle()
    
    function getTitle(): string {
        return "Dynamic Title"
    }
}

多层次与函数作用域

在复杂的组件层次中,使用 ID 来确保正确调用:

qml 复制代码
Item {
    id: parentItem
    
    Rectangle {
        id: childItem
        function childFunction() {
            console.log("Called child function")
        }
    }
    
    Button {
        text: "Call Child Function"
        onClicked: {
            childItem.childFunction()
        }
    }
}

动态函数重写

通过属性和函数指针实现函数重构:

qml 复制代码
Rectangle {
    width: 200
    height: 100
    id: root
    
    function defaultFunction() {
        console.log("Default function")
    }
    
    var currentFunction = defaultFunction
    
    Button {
        text: "Call Function"
        onClicked: {
            root.currentFunction()
        }
    }
    
    Component.onCompleted: {
        // 动态修改函数指针
        root.currentFunction = function() {
            console.log("New function called")
        }
    }
}

总结

  • 函数可以作为属性,具备灵活的参数和返回值类型。
  • 在复杂项目中,使用 ID 明确调用目标,保证函数的作用域正确。
  • QML 函数的语法与 JS 兼容,但在类型检查方面,QML 提供了更多的安全性。
  • 可以通过属性赋值将函数作为属性,利用其返回值动态设置属性值。
相关推荐
用户805533698033 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner3 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz8 天前
QML Hello World 入门示例
qt
xcyxiner11 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner12 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner12 天前
DicomViewer (添加模型类)3
qt
xcyxiner13 天前
DicomViewer (目录调整) 2
qt
xcyxiner13 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
LDR00615 天前
Type-C 快充全面升级!LDR6601 赋能个人护理便携电机,重塑剃须刀 / 理发器新体验
c语言·开发语言
雪碧聊技术15 天前
Tree.js是什么?一文讲透
开发语言·javascript·ecmascript