What's New in QML formatting
QML格式中的新功能
June 24, 2025 by Semih Yavuz | Comments
2025年6月24日由Semih Yavuz发表|评论
The latest updates to qmlformat, Qt's own tool for formatting of QML files, bring two practical improvements: configurable line breaking and automatic import sorting. These features enhance code readability and maintainability, making them valuable additions worth highlighting.
Qt自己的QML文件格式化工具qmformat的最新更新带来了两个实际改进:可配置的换行和自动导入排序。这些特性增强了代码的可读性和可维护性,使其成为值得强调的宝贵补充。
Line Breaking After Specified Length
指定长度后换行
Long lines of code can be difficult to read and navigate, particularly when working with complex QML components that have numerous properties.
长代码行可能难以阅读和导航,特别是在处理具有众多属性的复杂QML组件时。
As of Qt 6.9, qmlformat can automatically break lines that exceed a specified character length.
从Qt 6.9开始,qmformat可以自动打断超过指定字符长度的行。
Option | Description |
---|---|
-W , --column-width < width > | Breaks lines that exceed the specified width. Use -1 to disable line wrapping (default). 打断超过指定宽度的一行。使用-1禁用换行(默认)。 |
Line Breaking in Action
换行行为
You can specify a maximum line length, and qmlformat will intelligently break lines that exceed this limit. For example:
可以指定最大行长度,qmformat将智能地打断超过此限制的行。例如:
// main.qml
import QtQuick
import QtQuick.Controls.Material
import QtQuick.Templates as T
T.ItemDelegate {
id: control
highlighted: control.pressed || control.hovered || (control.ListView.view && control.ListView.view.currentIndex === index && control.ListView.view.highlightFollowsCurrentItem && control.enabled }
Using qmlformat without line breaking options makes this less readable:
使用qmformat而不使用换行选项会降低可读性:
import QtQuick
import QtQuick.Controls.Material
import QtQuick.Templates as T
T.ItemDelegate {
id: control
highlighted: control.pressed || control.hovered || (control.ListView.view && control.ListView.view.currentIndex === index && control.ListView.view.highlightFollowsCurrentItem && control.enabled
}
Using qmlformat -W 80 main.qml
produces a more readable result:
使用qmformat-W 80 main.qml可以产生更易读的结果:
import QtQuick
import QtQuick.Controls.Material
import QtQuick.Templates as T
T.ItemDelegate {
id: control
highlighted: control.pressed || control.hovered || (
control.ListView.view
&& control.ListView.view.currentIndex
=== index
&& control.ListView.view.highlightFollowsCurrentItem
&& control.enabled
Sorting Import Statements
排序导入声明
Managing cluttered or inconsistently ordered import statements can be challenging and often leads to unnecessary merge conflicts when multiple contributors modify the same file.
管理混乱或顺序不一致的导入语句可能具有挑战性,当多个贡献者修改同一文件时,往往会导致不必要的合并冲突。
To address these issues, Qt 6.10 introduces the --sort-imports
option in qmlformat. Sorted imports improve readability by clearly showing which modules are used, reduce merge conflicts by minimizing unnecessary diffs, and enforce a consistent structure across all QML files.
为了解决这些问题,Qt 6.10在qmformat中引入了--sort-imports
选项。排序导入通过清楚地显示使用了哪些模块来提高可读性,通过最小化不必要的差异来减少合并冲突,并在所有QML文件中强制执行一致的结构。
Option | Description |
---|---|
-S , --sort-imports | Sort imports alphabetically (Warning: this might change semantics if a given name identifies types in multiple modules!) 按字母顺序对导入进行排序(警告:如果给定的名称标识了多个模块中的类型,这可能会改变语义!) |
⚠️ Warning: Sorting imports alphabetically with --sort-imports
can change the semantics of your QML files if the same type name exists in multiple modules. Always review the results to ensure your application behaves as expected.
⚠️警告:如果多个模块中存在相同的类型名称,则使用--sort-imports
按字母顺序对导入进行排序可能会更改QML文件的语义。始终查看结果,以确保应用程序按预期运行。
Sort Imports in Action
排序导入行为
// Original main.qml
import QtQuick.Templates
import MyCustomModule
Button {
}
After running qmlformat -S main.qml
:
运行qmformat-S main.qml后:
import MyCustomModule
import QtQuick.Templates
Button {
}
In this example, the original main.qml uses MyCustomModule’s Button. Formatting with --sort-imports
changes the semantics to use the non-visual Button from QtQuick.Templates.
在这个例子中,原始的main.qml使用MyCustomModule的按钮。使用--sort-imports
格式化会更改语义,以使用QtQuick.Templates中的非可视化按钮。
Upcoming: Customizable Semicolon Rule
即将推出:可定制的分号规则
As of Qt 6.10, we’ve introduced a new –semicolon-rule option, giving users more control over how JavaScript semicolons are handled during formatting. The new flag supports two modes: always, which appends semicolons to all JS statements, and essential, which removes them unless omitting them would lead to ambiguity due to JavaScript’s automatic semicolon insertion (ASI) rules.
从Qt 6.10开始,我们引入了一个新的分号规则选项,使用户可以更好地控制在格式化过程中如何处理JavaScript分号。新标志支持两种模式:always,它将分号附加到所有JS语句中;essential,它删除分号,除非省略它们会导致JavaScript的自动分号插入(ASI)规则导致歧义。
Mode | Description |
---|---|
always | Appends semicolons to all JavaScript statements. (default) 在所有JavaScript语句后附加分号。(默认) |
essential | Removes semicolons unless ASI (Automatic Semicolon Insertion) makes it unsafe. 删除分号,除非ASI(自动插入分号)使其不安全。 |
Note: This option only affects semicolons at the end of JavaScript statements. Semicolons at the end of QML elements are always removed by qmlformat, regardless of the –semicolon-rule setting.
注意:此选项仅影响JavaScript语句末尾的分号。QML元素末尾的分号始终由qmformat删除,而不管分号规则设置如何。
As part of these semicolon rule improvements, the handling of EmptyStatements has also been refined: semicolons following control structures without bodies—such as if, for, or while—now appear directly after the closing parenthesis, rather than on a new, indented line. Additionally, multiple consecutive empty statements are collapsed into a single semicolon for a cleaner result.
作为这些分号规则改进的一部分,EmptyStatement的处理也得到了改进:没有正文的控制结构后面的分号(如if、for或while)现在直接出现在右括号后面,而不是出现在新的缩进线上。此外,为了获得更清晰的结果,多个连续的空语句被折叠成一个分号。
import QtQuick
Item {
Component.onCompleted: {
for(;;);;
;;
if (true);;;
;
while (true);
;
;;
var a = [1, 2, 3];;;;
for (var i in a);;;;
}
}
// qmlformat output prior to 6.10
import QtQuick
Item {
Component.onCompleted: {
for (; ; )
;
;
;
;
if (true)
;
;
;
;
while (true)
;
;
;
;
var a = [1, 2, 3];
;
;
;
for (var i in a)
;
;
;
;
}
}
// qmlformat output as of 6.10
import QtQuick
Item {
Component.onCompleted: {
for (; ; );
if (true);
while (true);
var a = [1, 2, 3];
for (var i in a);
}
}
Customizable Semicolon in Action
可定制的分号行为
// original test.js
let v = a;;;;;;
[1, 2, 3].forEach(x => console.log(x));;;;;
;;;
;;;
let x = v;;;
x = 10;;;
;
;;;
;
let y = x;;;
(function() { })();;
let a = b
+ c
;
let xx = y;
-x;
qmlformat --semicolon-rule=always test.js
adds semicolons at the end of JS statements.
qmlform--semicolon-rule=always
test.js在js语句末尾添加分号。
let v = a;
[1, 2, 3].forEach(x => console.log(x));
let x = v;
x = 10;
let y = x;
(function () {})();
let a = b + c;
let xx = y;
-x;
qmlformat --semicolon-rule=essential test.js
removes all semicolons, except those whose removal could lead to unintended behavior.
qmlform --semicolon-rule=essential
ltest.js删除所有分号,但删除可能导致意外行为的分号除外。
For example, the semicolon after let v = a; is not removed because the following line starts with a [ token:
例如,let v=a后的分号;未删除,因为以下行以[token:
let v = a;
[1, 2, 3].forEach(x => console.log(x))
let x = v
x = 10
let y = x;
(function () {})()
let a = b + c
let xx = y;
-x
In JavaScript, certain tokens at the beginning of a line—such as (
, [
, +
, or -
—can prevent automatic semicolon insertion (ASI) from working as expected. To avoid changing the semantics of the code, qmlformat
preserves semicolons in these cases.
在JavaScript中,行首的某些标记,如(、[、+或-,可能会阻止自动分号插入(ASI)按预期工作。为了避免更改代码的语义,qmformat在这些情况下保留分号。
qmlformat Integration in Qt Creator 17
Qt Creator 17中的qmformat集成
We’re pleased to announce that qmlformat is now integrated directly into Qt Creator 17, making QML code formatting more accessible and consistent across projects.
我们很高兴地宣布,qmformat现在已直接集成到Qt Creator 17中,使QML代码格式在项目之间更易于访问和一致。
When you select qmlformat
as your QML code formatter in Preferences under Qt Quick > Code Style, Qt Creator automatically detects the latest version of qmlformat
available on your system. It generates a default configuration by executing the command qmlformat --write-defaults
. You can customize this configuration based on your formatting preferences; additional information is available here. The global configuration is stored at QStandardPaths::GenericConfigLocation/.qmlformat.ini
.
当在“Qt Quick”>“代码样式”下的“首选项”中选择qmformat作为QML代码格式化程序时,Qt Creator会自动检测系统上可用的最新版本的qmformat。它通过执行qmlformat --write-defaults
命令生成默认配置。可以根据格式首选项自定义此配置;更多信息请点击此处。全局配置存储在QStandardPaths::GenericConfigLocation/.qmlformat.ini
中。
It’s important to understand how qmlformat
locates its configuration settings. During formatting, it first looks for a .qmlformat.ini
file in the directory of your source file. If no local configuration is found there, it searches up the directory hierarchy until it either finds a suitable configuration file or reaches the root directory. If no local configuration is found, it falls back to the global configuration stored in the generic config location.
了解qmformat如何定位其配置设置非常重要。在格式化过程中,它首先在源文件的目录中查找.qmlform.ini文件。如果在那里没有找到本地配置,它会向上搜索目录层次结构,直到找到合适的配置文件或到达根目录。如果没有找到本地配置,它将回退到存储在通用配置位置的全局配置。
This flowchart illustrates how qmlformat
searches for its settings file:
此流程图说明了qmformat如何搜索其设置文件:
[Start: QML file directory]
↓
[Is .qmlformat.ini here?] → Yes → [Use it]
↓ No
[Go to parent directory]
↓
[Repeat until root]
↓
[Still not found?] → [Use global config in GenericConfigLocation]
If you notice unexpected formatting behavior—formatting that doesn’t align with the settings you’ve defined in Qt Creator’s preferences—check whether a .qmlformat.ini file exists somewhere in your project’s directory tree. Such a file takes precedence over the global configuration and may override your intended style settings.
如果注意到意外的格式化行为——格式化与您在Qt Creator的首选项中定义的设置不一致——请检查项目目录树中是否存在.qmlform.ini文件。此类文件优先于全局配置,并可能覆盖预期样式设置。
qmlformat in Action in Qt Creator 17
qmlformat 在 Qt Creator 17 中的动作
In Qt Creator 17, we’ve introduced a new preferences section for configuring QML formatting options. To use qmlformat with your QML files, you’ll need to explicitly select it as your preferred formatter.
在Qt Creator 17中,我们引入了一个新的首选项部分,用于配置QML格式选项。要将qmformat用于QML文件,需要明确选择它作为首选格式化程序。
Setting up qmlformat in Qt Creator
在Qt Creator中设置qmformat
1.Navigate to Preferences > Qt Quick > Code Style
1.导航到“首选项”>“Qt Quick”>“代码样式”
2.Under the Formatter Selection dropdown, select QmlFormat[LSP]
2.在格式化程序选择下拉列表中,选择QmlFormat[LSP]
3.Adjust additional options like column width or import sorting according to your preferences under Global qmlformat configuration
3.在全局qmformat配置下,根据偏好调整列宽或导入排序等其他选项
Once you customize the Global qmlformat configuration
, the preview on the right side will update to show how your settings will appear when formatting a QML file.
自定义全局qmformat配置后,右侧的预览将更新,显示格式化QML文件时设置的显示方式。
Using qmlformat in your QML files
在QML文件中使用qmformat
After configuration, formatting your QML files is straightforward:
配置后,格式化QML文件很简单:
1.Open any QML file in the editor
1.在编辑器中打开任何QML文件
2.Right-click to open the context menu
2.右键单击打开上下文菜单
3.Select Reformat Document
3.选择“重新格式化文档”
Alternatively, you can access the reformat action through Tools > QQml/JS > Reformat Document.
或者,可以通过“工具”>“QQml/JS”>“重新格式化文档”访问重新格式化操作。
Note that if you’ve previously used Qt Creator’s Built-in Formatter, switching to qmlformat may produce different formatting results. This is expected as the two formatters use different algorithms and approaches to code styling. We recommend reviewing your code after the first formatting to ensure it meets your expectations.
请注意,如果之前使用过Qt Creator的内置格式化程序,切换到qmformat可能会产生不同的格式化结果。这是意料之中的,因为这两个格式化程序使用不同的算法和方法进行代码样式设置。我们建议在第一次格式化后检查代码,以确保它符合期望。
Using Another Version of qmlformat
使用qmformat的另一个版本
If you wish to use a specific version of qmlformat or your own fork, the Custom Formatter option is available. You’ll need to set the path and specify options in the arguments section. Please refer to the official qmlformat documentation for all available options.
如果希望使用qmformat的特定版本或自己的fork,可以使用自定义格式化程序选项。需要在arguments部分设置路径并指定选项。请参阅官方qmformat文档了解所有可用选项。
Additionally, wrapping qmlformat with your own script can help fasten the workflow. A simple shell wrapper allows you to customize qmlformat behavior for your needs. For example:
此外,用自己的脚本包装qmformat可以帮助加快工作流程。一个简单的shell包装器允许根据需要自定义qmformat行为。例如:
#!/bin/sh
# qmlformat-wrapper.sh
/path/to/your/qmlformat --indent-width 12 "$@"
chmod +x qmlformat-wrapper.sh
You can then use this script as your Custom Formatter by setting the script path and leaving the arguments section empty (or adding additional options as needed). Or simply point the Custom Formatter path directly to the qmlformat executable and pass your desired options in the arguments section:
然后,可以通过设置脚本路径并将arguments部分留空(或根据需要添加其他选项),将此脚本用作自定义格式化程序。或者,只需将自定义格式化程序路径直接指向qmformat可执行文件,并在参数部分传递所需的选项:
Note: Qt Creator currently uses its legacy formatter by default to preserve compatibility and user expectations. Because the two formatters are not guaranteed to produce identical output, using qmlformat by default in Qt Creator could lead to unexpected or unintentional changes in a user’s code style — especially in collaborative projects or existing codebases. Until the integration is more mature and aligned, Qt Creator leaves the choice to the user.
注意:Qt Creator目前默认使用其旧版格式化程序来保持兼容性和用户期望。因为这两个格式化程序不能保证产生相同的输出,在Qt Creator中默认使用qmformat可能会导致用户代码风格发生意外或无意的变化,尤其是在协作项目或现有代码库中。在集成更加成熟和一致之前,Qt Creator将选择权留给用户。
What’s Next?
接下来是什么?
With qmlformat now integrated into Qt Creator 17, working with QML just got a little easier. The new features—like automatic line breaking and import sorting—help keep your code clean, readable, and consistent. And since formatting is built right into Qt Creator, it’s just a couple of clicks away.
随着qmformat现在集成到Qt Creator 17中,使用QML变得更加容易。新功能(如自动换行和导入排序)有助于保持代码干净、可读和一致。由于Qt Creator内置了格式化功能,只需点击几下即可完成。
Looking ahead, we will be working on batch formatting for entire projects.
展望未来,我们将为整个项目进行批量格式化。
We’d love for you to give it a try and let us know what you think. Your feedback helps us make the QML tooling better for everyone.
我们希望能尝试一下,并告诉我们想法。反馈有助于我们使QML工具更好地为每个人服务。
Thanks for being part of the Qt community—happy coding with Qt Creator 17 and qmlformat!
感谢成为Qt社区的一员——使用Qt Creator 17和qmformat愉快地编码!