前言

C++ 作为元老级别的开发语言,那些前辈们已经帮助我们总结了很多基于 C++ 的开发模式,所以我们对 C++ 并不
陌生,但是 QML 作为一种新生的语言,在开发语言中是属于非常年轻的地位,且不知道是什么原因,也许正因为 QML
是一种新生语言,网上对于 QML 相关的资料比较欠缺,而且都是一些比较基础的。所以接触 QML 以来,就需要我们不
断去学习它,写笔记记录下我的种种经验,以便为后来者提供一条正确的参考方向。

我在写 QML Demo 代码时,发现代码混乱,模块分的不是很清楚,要知道,在 C++ 中,我们在开发时,首先想到的是
如何将各模块分的清清楚楚,使各模块有更好的解耦能力。在 QML 中写的 Demo 都混乱还得了,这是不能容忍的,必须
盘它。

不管是什么语言,良好的结构于编码风格是非常有必要的,不管你将任何一种开发语言作为编程语言,这些代码都是给人看
的嘛,程序员一定要让自己的代码成为有价值的代码。

目录

  • QML 开发模式概述

  • QML 开发

  • QML 与 Javascript 结合开发

  • QML 与 C++ 结合开发

  • 总结
  • QML 开发模式概述

    网络研讨会 | Qt Quick 与 Qt Widgets 适用场景及技术分析 的视频中有提到 QML 未来设想的开发模式官方的建议是
    Javascript 控制前端的页面逻辑,C++ 控制后端的具体逻辑处理,QML 就是纯粹的界面组件组合。

    但是 QML 借鉴了大量类似于 web 的风格,比如 QMLJavascript 就非常的相似,既然 Qt 官方 借鉴别个,
    那么我们也可以借鉴呀,既然 QML 借鉴类似于 Html + Css + Javascript 的组合,由于我的应用项目比较大,那
    些例子的开发模式并不能支撑我们直接拿来就用,就先不管 Qt 官方的那些例子吧。

    QML 开发

    你可能不需要或者不愿意使用 QML + Javascript 的开发模式,那么为了达到我们的需求,我们就只能另辟蹊径了,我
    们可以利用 QML 实现类似于 Javascript 的效果

  • main.qml
  • import QtQuick 2.12
    import QtQuick.Window 2.12
    import QtQuick.Controls 2.5
    
    Window {
    
        id: id_rootWindow
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
    
        Button {
    
            id: id_btnTestting
            text: "测试按钮"
    
            QmlButtonHandle { // 事件处理对象
    
                id: id_btnTesttingHandle
                target: id_btnTestting
            }
    
            QmlButtonStyle { // 按钮风格
    
                id: id_btnTesttingStyle
            }
    
            Component.onCompleted: { // 按钮完成初始化后进行事件绑定
    
                clicked.connect(id_btnTesttingHandle.btnClicked)
                released.connect(id_btnTesttingHandle.btnReleased)
            }
        }
    }
    

  • QmlButtonHandle.qml
  • import QtQuick 2.0
    
    QtObject {
    
        id: id_btnHandle
        property var target: null
    
        function btnClicked() {
    
            if(target !== null) {
    
                console.log(target.text + ": call clicked function for QmlButtonHandle.qml")
            }
        }
    
        function btnReleased() {
    
            if(target !== null) {
    
                console.log(target.text + ": call released function for QmlButtonHandle.qml")
            }
        }
    }
    

  • QmlButtonStyle.qml
  • import QtQuick 2.0
    
    Rectangle {
    
        anchors.fill: parent
        color: "red"
        radius: 10
    }
    

    以上还是看得出来 C++ 的习惯还是没有改掉,如果你不喜欢这样的话,你或许可以这样去实现:

    我通过同事了解到,Javascript 的开发模式中,他们常常是将 Javascript 的代码嵌入到
    Html 中,Html 通过 <script></script> 来支持他们这样使用,我同样也可以借鉴看看
    效果嘛。

    import QtQuick 2.12
    import QtQuick.Window 2.12
    import QtQuick.Controls 2.5
    
    Window {
    
        id: id_rootWindow
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
    
        Button {
    
            // <variable brief = "Class member variable initialization">
    
            id: id_btnTestting
            text: "测试按钮"
    
            // </variable>
    
            // <statement brief = "Member variable definition">
    
            property int var_count: 0
    
            // </statement>
    
            // <signal brief = "Signal definition">
    
            signal requstIncClickedCount()
    
            // </signal>
    
            // <event brief = "Event binding">
    
            onClicked: btnClicked()
            onReleased: btnReleased()
            onRequstIncClickedCount: incCount()
    
            // <event>
    
            // <styles>
    
            Rectangle {
    
                id: id_btnTesttingStyle
                anchors.fill: parent
                color: "red"
                radius: 10
            }
    
            // </styles>
    
            // <event_func brief = "Declaration and implementation of event handling method">
    
            function btnClicked() {
    
                requstIncClickedCount()
                console.log(text + ": call clicked function for btnClicked")
            }
    
            function btnReleased() {
    
                console.log(text + ": call released function for btnClicked")
            }
    
            function incCount() {
    
                ++var_count
                console.log("var_count: " + var_count)
            }
    
            // </event_func>
        }
    }
    
    QML 与 Javascript 结合开发

    Javascript 我不太熟悉,就直接上代码了

  • JavaScriptObject.js
  • /** 全局变量 */
    var globalVariable = 0
    
    /** 全局变量: 主窗口标题栏 */
    var mainWindowTitle = "Js参数"
    
    /** 全局变量: 测试按钮文本信息 */
    var testtingBtnText = "测试按钮"
    
    /**
        \brief  输出 Hello World 到控制台,并输出该方法响应次数
    */
    function printHelloWorld() {
    
        console.log("function printHelloWorld: [%1] %2".arg(++globalVariable).arg("Hello World"))
    }
    

  • main.qml
  • import QtQuick 2.12
    import QtQuick.Controls 2.5
    import "JavaScriptObject.js" as JavaScriptObject
    
    ApplicationWindow {
    
        id: id_rootWindow
        visible: true
        width: 640
        height: 480
        title: JavaScriptObject.mainWindowTitle
    
        Button {
    
            id: id_btnTestting
            text: JavaScriptObject.testtingBtnText
    
            onClicked: JavaScriptObject.printHelloWorld()
        }
    }
    
    QML 与 C++ 结合开发

    这段我就不说了,我之前记录了笔记在 QML之C++混合编程理解

    总结

  • 因为我是C++程序员,我更倾向于 Javascript + QML + C++的模式来开发,这样能让我们的大模块拆分很多小模块,
    最终的结果就是每个模块都是很小、耦合度非常底的,这也是我们开发的偷懒大法不是
  • QML的方式个人觉得太臃肿了,这也可能是本人对其理解不深,不过时间会证明一切。
  • posted on 2020-12-22 15:36  怪小子  阅读(908)  评论(0编辑  收藏  举报