Qt Quick Style Generator: Automating Qt Quick Styling with Figma

A Qt Quick Controls style defines the visual representation of the controls. By overriding the control’s visual “delegates” such as the background, content item, or other components, developers can implement unique looks and styles for these controls. Sometimes these styles can include complex visual elements or intricate effects and reproducing them in QML can be challenging for a style designer or someone with limited QML experience. But one doesn’t have to know the ins and outs of QML to be able to write a style. With the qqstylegenerator tool, creating a Qt Quick Controls style becomes a seamless process by automating much of the manual effort.

qqstylegenerator is a tool designed to create ready-to-use Qt Quick Controls styles from Figma designs. By using predefined Figma templates, it helps developers easily produce consistent and visually appealing styles without much hassle.

Figma templates

Qt Quick Style Generator Figma Templates

A key part of the tool are the Qt Quick Style Generator Templates, which are used as a basis for designing the controls. These templates leverage Figma's variables system to manage essential design attributes and are designed to closely match the structure and semantics of Qt Quick Controls.

Templates provide a structured approach for users to design and implement Qt Quick Controls styles effectively. Each template is tailored to a specific control like button, checkbox, and others. By following established patterns, the templates ensure consistency and adherence to the rules for Qt Quick Controls. They also help users map design elements to the correct QML components of each control, allowing designers to focus on creativity without being burdened by implementation details.

The components in Figma are designed to closely mimic the structure, naming, and behaviour of controls in Qt Quick, ensuring a seamless transition between design and implementation. Each component aligns with the corresponding control delegate, such as a background or an indicator, which is represented as layers in the Figma templates components. Additionally, we have introduced things like Layout components which closely reflect how a control layout behaves, with the contentItem positioned within the background area and adjusted based on the specified padding. The templates also include multiple states for each control, carefully mapped to the various states of the corresponding Qt Quick control. By imitating the architecture and semantics of Qt Quick Controls, these components enable designers to create controls that are both visually accurate and functionally consistent with the underlying code.

Template structure

 To manage key design attributes such as colors, spacing, and corner radii, the new variables system in Figma is used. This system allows for the definition of themes, making it easier to manage style variations like light mode and dark mode. By centralising these definitions, the variables system promotes consistency across all components and simplifies the process of updating or modifying themes. With light and dark modes already set up, users can seamlessly switch between themes while maintaining visual and functional harmony.

Tool

The second important component of the style generator is the qqstylegenerator tool. This tool provides both a command-line and graphical user interface, and takes the Figma file ID, representing the design file to generate the style from, as argument. It also allows flexibility by setting several other options. These include options to specify the target directory, generate specific controls, define image formats and resolutions, and set a fallback style. The output includes a fully defined style package: a qmldir file for registration, a .qrc file, QML templates for controls, a CMake module for easy integration, and image assets ready for use in applications. The generated style is image-based, which means the visual assets are exported as images to represent the controls.

How does it work?

The tool works by using the Figma REST APIs to download a JSON representation of the Figma file, providing a structured view of the design. A separate configuration JSON file is specified, detailing the elements (or "atoms" as they’re called in Figma) to be exported for each control, as well as the states of those controls. For each control and its corresponding states, the tool exports the assets and configuration needed to reflect the design accurately. The exported information includes key properties like sizing, layout details such as paddings, offsets, and radiuses, as well as images for the relevant atoms. Once all the data is processed, the tool generates a QML configuration file, which consolidates all the exported information. This configuration object and its properties are then directly used in the style’s control templates to provide the necessary information.

Building the FluentWinUI3 Style with StyleGenerator

The StyleGenerator tool was instrumental in creating the new FluentWinUI3 style for Qt Quick Controls. The process began with designing the controls in Figma, following Microsoft's Fluent and WinUI3 guidelines, and using the Figma Quick Controls templates as a starting point. Each control was designed to match the Fluent specifications and maintain a consistent look and feel. Once the designs were finalised, they were exported from Figma and processed through the qqstylegenerator tool to generate the necessary assets and configurations.

FluentWinUI3 Templates in Figma

The tool generated assets and configurations for each control and its states, including images and layout details. However, certain controls required additional modifications. For example, in the FluentWinUI3 style, controls like the ComboBox and other text controls needed angled accent-coloured strokes at the bottom when focused, which were implemented directly in QML. Other enhancements, such as animations and transitions not included in the Figma designs, were also added in QML. The tool's ability to preserve manual edits to template files during subsequent runs made it easier to integrate these custom changes and refine the controls without losing previous modifications. This allowed us to refine the controls without worrying about losing modifications.

With the qqstylegenerator tool, the Fluent style was implemented accurately and efficiently. While manual modifications were still necessary for certain features, the tool significantly streamlined the process. The final results demonstrated how effectively the tool translated the Figma designs into implementation, combining automation with flexibility to deliver a polished, functional style.

side-by-side comparison

How to Create Your Custom Styles with qqstylegenerator

Creating your own custom styles with Qt Quick Style Generator is a straightforward process. Start by implementing your design into your own copy of the Figma templates provided, which includes detailed documentation to guide you through every step. You can modify building blocks, or what we call “primitives”, as well as global variables such as radii, sizes, etc. , and the changes will take effect in all the control components.

If you require more specific adjustments, you can dive deeper into the main components. For instance, you can make broader changes to elements like backgrounds or indicators. For highly specific needs, such as altering the appearance of a slider only on hover, the template enables you to navigate directly to that state and make precise modifications.

Whether you’re changing the layout, background, or indicator, the template’s step-by-step instructions make the process intuitive. Once your adjustments are complete, you can use the preview section in Figma to test how your design looks across various states and scenarios.

Once you have defined the templates, the next step is to retrieve the Figma file ID for the file containing your templates. You will also need to generate a Figma access token to enable the tool to access your designs. With these prerequisites complete, you are ready to use the qqstylegenerator tool. The tool is available in this repository. Once built, you can run the tool using either the command-line or the graphical user interface.

To use the tool, specify the Figma file ID and access token you retrieved earlier. Additional options can be configured through the GUI or directly via the command line. For instance, the following command generates styles for selected controls with specific image formats:

qqstylegenerator --directory /path/to/output --token YOUR_FIGMA_TOKEN --generate Button --generate Slider --format png@2x --format png@3x --fallbackstyle Fusion YOUR_FIGMA_FILE_ID

 

qqstylegenerator tool running

Once the tool completes the process, developers should review the generated files and image assets. Any necessary refinements or adjustments can be made at this stage to ensure the style meets the application's requirements. The tool supports an iterative process where the changes made to the QML files won't be overridden after tool re-runs.

Finally, the generated style can be integrated into a Qt application. You can use the style in your project in several ways. If you include the style’s CMake module directly in your CMake project and link to it, you can then set the style normally through compile-time or run-time selection. For more information on using and setting Qt Quick Controls styles, see Using Styles in Qt Quick Controls. Alternatively, by setting the QML_IMPORT_PATH environment variable, the application can load the style dynamically, by specifying the style name as a runtime argument (-style MyStyle). Another option is to embed the style into the application as a resource using the provided .qrc file, allowing you to import the style directly from the resource path in QML. By leveraging Figma designs and the automation provided by qqstylegenerator, the workflow of creating and applying custom styles becomes both efficient and straightforward.

 

Experimental State

This work represents an experimental project from our qt-labs and is currently in its beta state. We encourage designers and developers to explore the templates, run the tool, try them out in their workflows, and provide us with feedback. Your input will be invaluable in refining and enhancing the tool.

 

Useful Links


 


Blog Topics:

Comments

Commenting for this post has ended.

Serhii Olendarenko
0 points
3 months ago

Why are there color differences between the app and the Figma template on your comparison picture?

D
Doris Verria
0 points
3 months ago

The color differences are because the FluentWinUI3 style respects the system accent color, which is used to fill that background. For certain controls with elements that require system colors, such as the accent color, we’ve made specific modifications in QML to manually apply them.

Mikio Hirai
0 points
3 months ago

This project is so cool! I love it.

I’ve just tried it out and have a question. The article says it can handle possible conflicts between the already-exported .qml files and additional changes in the Figma design.

My understanding is that a user of this tool would manually modify each control’s QML file (e.g., Button.qml) to adjust how it looks. Meanwhile, the qqstylegenerator tool primarily updates Config.qml and image files, so the files we modify by hand and the files the tool updates are separated. That separation should prevent any merge conflicts. Is this correct?

If it is, then I assume the changes made to control files like Button.qml take precedence over changes made in Figma. For example, I changed the Button’s background to a Rectangle in Button.qml like so:

// background: StyleImage { // imageConfig: control.config.background // } background: Rectangle { implicitWidth: 100 implicitHeight: 40 visible: !control.flat || control.down || control.checked || control.highlighted color: Color.blend( control.checked || control.highlighted ? control.palette.dark : control.palette.button, control.palette.mid, control.down ? 0.5 : 0.0 ) border.color: control.palette.highlight border.width: control.visualFocus ? 2 : 0 }

Then, I changed the radius of the Button’s background in Figma and re-ran the generation process. The generator overwrote the original output, but the change in Button.qml (using Rectangle for the background) was still preserved. This confirms my understanding.

When I look at git status, it shows changes in Config.qml and a bunch of PNG images for the button’s background in both light and dark modes, but no changes in Button.qml. That suggests the tool only updates those assets and leaves my custom QML edits alone:

git status modified: output/Config.qml modified: output/dark/images/button-background-checked-disabled.png modified: output/dark/images/button-background-checked-disabled@2x.png modified: output/dark/images/button-background-checked-hovered.png modified: output/dark/images/button-background-checked-hovered@2x.png modified: output/dark/images/button-background-checked-pressed.png modified: output/dark/images/button-background-checked-pressed@2x.png modified: output/dark/images/button-background-checked.png modified: output/dark/images/button-background-checked@2x.png modified: output/dark/images/button-background-disabled.png modified: output/dark/images/button-background-disabled@2x.png modified: output/dark/images/button-background-hovered.png modified: output/dark/images/button-background-hovered@2x.png modified: output/dark/images/button-background-pressed.png modified: output/dark/images/button-background-pressed@2x.png modified: output/dark/images/button-background.png modified: output/dark/images/button-background@2x.png modified: output/light/images/button-background-checked-disabled.png modified: output/light/images/button-background-checked-disabled@2x.png modified: output/light/images/button-background-checked-hovered.png modified: output/light/images/button-background-checked-hovered@2x.png modified: output/light/images/button-background-checked-pressed.png modified: output/light/images/button-background-checked-pressed@2x.png modified: output/light/images/button-background-checked.png modified: output/light/images/button-background-checked@2x.png modified: output/light/images/button-background-disabled.png modified: output/light/images/button-background-disabled@2x.png modified: output/light/images/button-background-hovered.png modified: output/light/images/button-background-hovered@2x.png modified: output/light/images/button-background-pressed.png modified: output/light/images/button-background-pressed@2x.png modified: output/light/images/button-background.png modified: output/light/images/button-background@2x.png I just wanted to confirm if this behavior is the intended design. If so, it’s great that it cleanly separates the user’s custom QML changes from the auto-generated parts!

D
Doris Verria
0 points
2 months ago

Hi, thanks for trying it out and for the feedback! Yes exactly, the tool is designed to not override changes made to the controls QML files in order to allow the developer to make their own edits to the style.

Mikio Hirai
0 points
3 months ago

I have another question. Are there any specific considerations when using this tool, especially for embedded Linux devices with limited memory? I noticed that Config.qml can be quite large (for example, mine is around 23,747 lines).

I’m not entirely sure if the file size directly impacts memory usage in QML, but I wanted to confirm. If it does matter, are there any known workarounds or best practices for reducing the memory footprint?

D
Doris Verria
0 points
2 months ago

Memory footprint can be something to consider when using the tool. The size of Config.qml may impact memory usage, and the exported images will also contribute to the overall memory footprint. For reference, the FluentWinUI3 style uses around 3MB. The images can consume significant memory, especially if multiple resolutions (1x, 2x, and 3x) are exported. However, on embedded devices targeting a specific resolution, only one version would typically be needed, reducing the overall footprint. Necessary optimizations can be explored later, such as shifting more styling logic to QML instead of images, etc.

Mikio Hirai
0 points
3 months ago

I have another question: how can we use the qqstylegenerator alongside Qt Bridge for Figma? In my experiments, whenever I use components from the Figma Quick Controls Templates, Qt Bridge for Figma also generates files like Button.qml, which duplicates the files produced by qqstylegenerator. Is there a recommended best practice for using both tools at the same time?