• 【qml】QML最佳实践01



    QML 和 Qt Quick拥有许多优点,但在某些情况下,也有一些点需要注意。本文将描述在Qt QML开发中的三个最佳实践方法。

    一、自定义UI控制元素

    现如今,流畅、现代、高端大气的UI是目前任何一个应用程序成功的关键,这一点,也是QML对设计人员或开发人员意义重大的地方。在实的应用程序开发中,Qt提供了最基本的UI控件,这些控件是创建一个流畅和现代的UI所必需的东西。因此,当在我们的实际工程开发中,应事先浏览一下Qt提供的控件,如果没有符合我们自己的需求效果的,我们才去创建自定义的控件。(如何创建自定义控件,后续小生会写一篇来描述其大致过程和思路)


    我们可以通过以上“字母索引”寻找查看需要的QML类型。

    二、将UI与逻辑分离

    在我们实际应用程序开发过程中,为了创建可维护的应用程序,需要分离用户界面与业务逻辑。QML对UI的设计和开发有着较好的支持,主要有以下三点原因:

    (1)QML属于声明性语言,它非常适合用于描述UI,因为UI元素之间往往呈现嵌套和级联的特性。

    (2)在QML中,我们可以很容易使用JavaScript来响应事件。

    (3)相对于C++来说,QML代码编写要简单许多。

    C++作为一种强类型语言,最适合应用程序的逻辑开发。通常,这类代码会去执行复杂的计算或数据处理等任务,使用C++来实现会比QML更快。

    综上,QML适合用于用户界面的开发,C++适合用于程序逻辑(大量计算和数据处理等)的开发,在实际使用中,我们可以按照这个规则进行开发。

    三、在C++中与QML交互

    Qt允许我们从C++操作QML,但是不建议这样做。为了解释原因,让我们看一个简单的例子。

    (3-1)在C++中提取QML引用

    这里假设我们正在开发一个设置页面,其QML代码如下:

    import QtQuick 2.15
    import QtQuick.Controls 2.15
    
    Page {
        Button {
            text: qsTr("Restore")
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    这个时候,我们希望按钮在被单击时在C++中做一些事情。我们知道QML中的对象可以像在C++中一样发出更改信号,所以我们给按钮定义一个objectName,这样我们就可以从C++中找到QML中的按钮:

    Button {
        objectName: "restoreButton"
        text: qsTr("Restore")
    }
    
    • 1
    • 2
    • 3
    • 4

    然后,在C++代码中,我们找到该对象并连接到它的更改信号:

    #include 
    #include 
    #include 
    
    class LogicHandle : public QObject
    {
        Q_OBJECT
    
    public:
        LogicHandle() {}
    
    public slots:
        void restoreDefaults() {
            settings.setValue("loadLastProject", QVariant(false));
        }
    
    private:
        QSettings settings;
    };
    
    int main(int argc, char *argv[])
    {
        QGuiApplication app(argc, argv);
    
        QQmlApplicationEngine engine;
        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
        if (engine.rootObjects().isEmpty())
            return -1;
    
        LogicHandle backend;
    
        QObject *rootObject = engine.rootObjects().first();
        QObject *restoreDefaultsButton = rootObject->findChild("restoreButton");
        QObject::connect(restoreDefaultsButton, SIGNAL(clicked()),
            &backend, SLOT(restoreDefaults()));
    
        return app.exec();
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    上述代码中,在C++中通过objectName找到了QML中的按钮,然后使用connect()函数进行按钮点击信号和槽函数的关联。那么,使用这种方式让QML与C++之间进行交互会有一个问题:

    C++逻辑层依赖于QML表示层。

    如果当我们改变了objectName,或者由于某些原因造成C++查找QML对象逻辑破坏,这时候我们需要修改的地方就变得非常的多(QML和C++都需要修改)且代码之间的变得高度耦合,这将是一件无趣且糟糕的事情!

    因此,为了避免这种问题的出现,在QML与C++进行交互的时候,可以使用下文所述的方法:将C++类对象注册到QML中

    (3-2)将C++类对象注册到QML中

    重构QML比重构C++要容易得多,所以为了让维护变得轻松,我们应该尽量让C++类型不知道QML。这可以通过将对C++类型的引用“推”到QML中来实现:

    int main(int argc, char *argv[])
    {
        QGuiApplication app(argc, argv);
    
        LogicHandle backend;
    
        QQmlApplicationEngine engine;
        
        //将LogicHandle类的实例backend注册到QML上下文中
        engine.rootContext()->setContextProperty("backend", &backend);
        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
        if (engine.rootObjects().isEmpty())
            return -1;
    
        return app.exec();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    然后在QML直接调用C++槽函数:

    import QtQuick 2.15
    import QtQuick.Controls 2.15
    
    Page {
        Button {
            text: qsTr("Restore")
            onClicked: backend.restoreDefaults()
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在上述代码中,对于按钮的点击事件处理则放到了QML中,且在QML中通过注册的C++类访问到其槽函数。

    使用这种方法,即使将来QML代码可能会需要重构,但是C++代码是不会受到任何影响的。

    四、总结

    本文似乎是更倾向于经验性总结的文章,描述了在QML开发中的三个最佳实践方式:

    (1)在自定义QML控件之前我们应该做的事情——查找、检索、验证Qt官方提供的QML类型;

    (2)UI和逻辑分离的开发方式:QML适合用于用户界面的开发,C++适合用于程序逻辑(大量计算和数据处理等)的开发;

    (3)在C++中与QML交互,虽然该种方式不推荐使用,但也是值得了解的。推荐在QML中与C++交互

    对于QML来说,经小生多个版本的使用对比得出一结论:强烈推荐使用Qt 5.13版本以上的QML,过低的QML版本就不要去用了。

  • 相关阅读:
    Jmeter 之 “查看结果树” 界面功能介绍
    Hadoop完全分布式搭建
    金仓数据库KingbaseES客户端应用参考手册--21. kbbadger
    打破总分行数据协作壁垒,DataOps在头部股份制银行的实践|案例研究
    MySQL-DDL语句
    YOLOPv2开源,目标检测&区域分割,多任务版本
    查询快递单号物流,自动识别出物流是否签收
    一种自动化九点标定工具原理(包涵部分源码)
    计算机毕业设计django基于Python在线酒店管理系统(源码+系统+mysql数据库+Lw文档)
    java字符串的学习总结
  • 原文地址:https://blog.csdn.net/iriczhao/article/details/126456770