• 如何编写整洁的Qml代码


    如何编写整洁的Qml代码

    无疑,使用Qml技术能够开发出符合当前趋势的杰出的用户界面。Qml语言有着简洁和易学的语法,但代码并非天然就有清晰的层次。如果不注意,很容易搞乱。因此,需要学习如何编写整洁的Qml代码,以使你的程序易于维护。进而节省成本和时间。

    Qml代码整洁的关键

    到底是什么使得Qml代码整洁?本文从这一问题出发。代码会一团糟吗?是的,如果你不意识到这一点,会不小心在很多地方做错。

    Qml代码格式

    代码的风格主是代码格式化的方式。是代码看起来的样子。我发现这个定义非常平实易懂。它虽然不影响程序的运行,但它确实影响了代码的可读性。所以,它影响了程序的可维护性,也会耗费开发者未来做出改变的时间。
    代码的格式涉及缩进、空格及换行的使用、代码分组及组织。这大多关乎个人习惯,没必要为诸如括号应该在哪儿这样的小问题较真。目标是在整个项目中有一致的代码格式。我见过有的软件开发者自已都没有一致的代码格式,那在多人在同一代码库中协同开发时就更显困难。这是尝试自动代码格式的原因。

    Tip #1 更好的代码格式

    Qml 代码倾向于有许多嵌套级别,并且代码很快就会向右延伸太多。因此,我的第一个建议是,将缩进减至2个空格以降低影响。
    为了能实现这个目的,进入Qt Creator 的Tools->Options菜单,并找到Qt Quick设置。会找到一个关于代码风格的Tab页。你无法修改默认风格,但可以点Copy铵钮以创建自己的风格。
    为自己新建的代码风格命名后,点击Edit按钮来为新风格修改细节。这里可以调整更多细节,但至少先将缩进做下修改。你会看到缩进和Tab的大小都是4。将它们减至2。这些更改应会反映在代码编辑器和重新格式化文件等工具中。

    Tip #2 更好的代码格式

    另一个提示就是使用 QML/JS重新格式文件 工具。它是如何工作的?它将你的代码重新模式化并让其看上去更好一些。看下下面的组件。

    1. import QtQuick 2.0 
    2.  
    3. Item 
    4. { 
    5. id: root 
    6.  
    7. width:30;height:50; 
    8.  
    9. Text { 
    10. id: textItem 
    11. font.pixelSize: 48; wrapMode: Text.WordWrap 
    12. lineHeight: 0.75 
    13. Behavior on color { ColorAnimation { duration: 120; easing.type: Easing.OutElastic} } 
    14. states: [State { 
    15. name: "pressed" 
    16. when: mouse.pressed 
    17. PropertyChanges { 
    18. target: textItem 
    19. color :Qt.lighter(root.color) 
    20. }} 
    21. ] 
    22. } 
    23.  
    24. MouseArea { 
    25. id: mouse 
    26. anchors.fill: parent 
    27. onClicked: { 
    28. // ... 
    29. } 
    30. } 
    31.  
    32. function foo() 
    33. { 
    34. // ... 
    35. }} 

    这肯定不是你见过的最漂亮的代码。它有很多问题,包括每行的缩进都不同、错误的花括号位置、有时缺失空格、有时又有多余的空格。想快速修复它,从Qt Creator的顶部菜单栏找到Tools菜单,然后在QML/JS组里找到Reformat file。运行这个工具可以节省大量时间。

    1. import QtQuick 2.0 
    2.  
    3. Item { 
    4. id: root 
    5.  
    6. width: 30 
    7. height: 50 
    8.  
    9. Text { 
    10. id: textItem 
    11. font.pixelSize: 48 
    12. wrapMode: Text.WordWrap 
    13. lineHeight: 0.75 
    14. Behavior on color { 
    15. ColorAnimation { 
    16. duration: 120 
    17. easing.type: Easing.OutElastic 
    18. } 
    19. } 
    20. states: [ 
    21. State { 
    22. name: "pressed" 
    23. when: mouse.pressed 
    24. PropertyChanges { 
    25. target: textItem 
    26. color: Qt.lighter(root.color) 
    27. } 
    28. } 
    29. ] 
    30. } 
    31.  
    32. MouseArea { 
    33. id: mouse 
    34. anchors.fill: parent 
    35. onClicked: { 
    36. // ... 
    37. } 
    38. } 
    39.  
    40. function foo() {// ... 
    41. } 
    42. } 

    如果你有足够的决心放弃Qt Creator对Qml代码格式的一些控制,那么试着设置“Reform file”工具,以便在文件保存时自动运行。

    QML代码规范

    代码规范/约定超越了代码格式的范畴。Qml代码可以被格式化,从代码整洁的角度看上去很好,但它仍需要打磨。官方的规范是非常好的开始,请按官方建议来做。
    以下是我们遵循的,以提供高质量Qt Qml软件开发服务和整洁的Qml代码为目的的规范。我们也会要求应聘者完成技术分工时遵循这些规范。

    1.根项id

    为了提高可读性和可追溯性,建议将文件中的顶级元素命名为root。然后,在每个文件中,你就会知道 root是指向的是顶级元素。

    1. import QtQuick 2.0 
    2.  
    3. Item { 
    4. id: root 
    5. } 

    2.Qml字符转换

    对用户可见的字符应该都被qsTr()函数包含。 此外,不要使用结束翻译作为默认显示的字符串,而是使用 THIS_NOTATION。比如,不要写成qsTr("This is displayed"),而应该写成qsTr("THIS_IS_DISPLAYED")。多亏了这种方法,如果任何字符串缺少翻译,我们可以立即在 UI 中看到。

    3.有私有对象

    在 Qml 代码里,封装和适当的范围界定很重要。就象在C++ 中不能让类的所有成员都是公有的,在Qml代码中也是一样。并非所有的属性与函数都对外可见。经常有一些帮助属性或方法,它们没有值,甚至当从外部访问时会产生危害。因此建议将其包装成内部Qt对象。

    1. QtObject { 
    2. id: _ // or id: internal 
    3.  
    4. readonly property real timeout: 1000 
    5. property bool isExpanded: false 
    6.  
    7. function addDestination() { 
    8. // ... 
    9. } 
    10. } 

    4.各类属性的顺序

    官方的规范里涵盖了属性顺序,我们定义的略微不同,且更为细节。这在大型项目中会有回报。

    1. import QtQuick 2.15 
    2. import QtQuick.Controls 2.15 // Qt modules first 
    3. import com.scythestudio.ownmodule 1.0 // then own modules 
    4. import "./controls/" // then local directories 
    5.  
    6. // A hypothetical custom button item. 
    7. Item { 
    8. id: root 
    9.  
    10. /// The text to be placed on the button 
    11. property string title: "title" // properties declaration 
    12. /// The button's background color 
    13. property alias color: button.color 
    14.  
    15. signal buttonClicked() // signal declaration 
    16.  
    17. Button { // child items 
    18. id: button 
    19.  
    20. width: parent.width // properties derived from Item 
    21. height: parent.height 
    22.  
    23. icon.color: "black" // Button's own properties 
    24.  
    25. onClicked: { 
    26. root.buttonClicked() 
    27. } 
    28. } 
    29.  
    30. states: State { // states 
    31. name: "selected" 
    32. PropertyChanges { target: button; icon.color: "red" } 
    33. } 
    34.  
    35. transitions: Transition { // transitions 
    36. from: "" 
    37. to: "selected" 
    38. ColorAnimation { target: button; duration: 200 } 
    39. } 
    40.  
    41. PropertyAnimation { // special items 
    42. id: closeDelayAnimation 
    43. // ... 
    44. } 
    45.  
    46. Timer { // special items 
    47.  
    48. } 
    49.  
    50. Connections { // special items 
    51. target: someCppController 
    52.  
    53. function onProcessFailed() { 
    54. // ... 
    55. } 
    56. } 
    57.  
    58. QtObject { // private item 
    59. id: _ 
    60.  
    61. readonly property real timeout: 1000 
    62. property bool isExpanded: false 
    63.  
    64. function addDestination() { 
    65. // ... 
    66. } 
    67. } 
    68.  
    69. onWidthChanged: { // slots 
    70.  
    71. } 
    72.  
    73. function close() { // public functions 
    74. isExpanded = false 
    75. closeDelayAnimation.start() 
    76. } 
    77. } 

    以上代码片段可以得出很多规范,这里强调三条:

    • 函数定义倾向于放在文件底部,以便首先看清组件的子项,并快速理解元素是如何构建的。
    • 状态和转换往往会快速增长,这就是为什么它们应该放在子项的下面,尽管它们也是属性;
    • 组件的公有API应该被详细记录

    Qml最佳实践

    Qt框架文档中,可以找到Qml和Qt Quick的最佳实践。这些非常有用,且其中不少的要义是关于代码整洁的。最为关键的一条是将UI与逻辑分离的原则。当写Qml代码时,可能会尝试使用Qml和JavaScript实现很多事情,包括应用程序逻辑和网络交互。
    应该将这些事情放在C++ 中处理,这样前端写的Qml和后端写的C++ 才有清晰的分界线。也因此,程序结构会有更好的可扩展性。数据模型几乎总是应该在C++ 中实现。仅当模型数据是静态的时,才有可能在Qml代码中处理。否则,可能将在处理Qml模型高级操作而浪费时间,或在C++ 重写模型。
    另一个好的做法是使用qmllint 工具,有助于定位Qml代码中问题。这是一个相当有用的工具,可以警告很多问题,包括未使用导入和对属性的不例规访问。Qt公司现正为此工具与Qt Creator IDE更好地结合而努力。

    整洁的代码为何至关重要

    这一点上你应该理解整洁的代码意味着什么,以及你应该如何来确保所写代码符合规范。接下来我们来回答为何编写整洁的代码至关重要。这实际上是为了高质量的代码。当遵循一系列的规范和约定,很容易来定位问题,也会节省大量时间。此外,由于干净的代码概念包括良好的实践,遵循这些指引的开发人员编写代码具有艺术性。在审查过程中不需要费多大劲。
    当编写代码时,需要做出许多微小的决定,并且在一段时间后查看相同的代码之后,您宁愿不知道为什么要以特定方式编写代码。另一方面,当您遵循干净的 Qml 代码规则时,您会将这些小决定外包给代码。它可以释放你的思维资源。
    最后,当然,编写干净的 Qml 代码最重要的原因是它显着提高了项目的可维护性。有人说你写了一次代码,但它被读了多次。因此,你需要关心代码的可读性以及所有良好实践。然后,你和其他开发人员更容易进入项目,了解特定部分并进行更改。
    现在你可能会问你的团队应该对遵循干净的 Qml 代码规则有多严格。好吧,这一切都取决于你当前正在进行的项目的规模。未来有多少人参与或将参与也很重要。我的观点是,在确保高质量代码方面努力永无止境。即使你准备了一个小演示来展示哪些代码将被公开,遵循所有这些规则以最终对你的工作结果感到满意是件好事。一段时间后,它进入血液,开发人员甚至不再将其视为额外的努力。
    如果你在维护一个长期项目,例如 Qt 框架,您有很多理由对代码质量进行严格限制。我在一篇博文中描述了我在 Qt Charts in Qt 6.2 做贡献的经历。有很多约定和规则要遵循,实际上一开始很难习惯它们。虽然有 CI/CD 机制可以节省审阅者的时间,例如,寻找错别字。一开始,让我的代码符合所有这些要求是一件很困难的事。尽管如此,我知道这是这个项目的必备品,我可以说它甚至是令人愉快的。

    要点和一般规则

    • 维护一个干净的 Qml 代码库是一个健康的 Qt 项目的一个重要方面;
    • KISS--保持简短和简单。不是为你,而是为读者。始终选择更简单的实现选项而不是更复杂的实现选项;
    • 记录已创建项目的公共接口 (API);
    • 不要添加描述如何实现某事的注释。如果读者无法从您的代码中推断出这一点,那么代码就需要重构。注释如果写的解决方案不明显,可能看起来令人莫名其妙;
    • 不要重新造轮子;
    • 代码应适配现有的代码库。如果有改进想法,请先与其他开发人员讨论;
    • 遵循编码以及良好Qml实践的规范。

    参考:How to write clean Qml code in 2022?

  • 相关阅读:
    js设计模式 -- 拷贝模式
    超简单的SpringBoot整合mybatis
    使用JS调用手机本地摄像头或者相册图片识别二维码/条形码
    SpringBootsad整合EhCache做缓存处理
    调用微信的扫一扫功能详解说明---(java 排坑版)
    获取系统文件的创建日期
    在windows上获取文件创建时间
    简单计算器
    lambda-基于谓词筛选值序列
    IEnumerable<T>和IQueryable<T>区别
  • 原文地址:https://www.cnblogs.com/sammy621/p/16181340.html
Copyright © 2020-2023  润新知