How do I split my QML code into multiple files? - qt

I have just started playing with QML and have a view where I have a bunch of components as follows:
Window {
....
property Component dateTumbler: ControlView {
// Definition follows
}
property Component timeTumbler: ControlView {
// More definition follows
}
// More controls
}
This makes the main QML file very long and cumbersome to edit and maintain. I tried to separate this into different files as follows:
// DateTumblerView.qml
component: DateTumblerView { // Not sure how to inherit here..
// Definition here
}
I'm trying to use it like this:
property component dateTumbler: DateTumblerView {}
However, this never works and the DateTumblerView is never found. I am not sure if I am doing this correctly.
[EDIT]
ControlView is defined as follows:
import QtQuick 2.2
import QtQuick.Controls 1.1
import QtMultimedia 5.5
Rectangle {
id: view
property bool darkBackground: false
Text {
id: textSingleton
}
SoundEffect {
id: playCalSound
source: "qrc:/sound/test.wav"
}
}
[END EDIT]
What is the proper way to split QML code into multiple files?

Your DateTumblerView.qml file should look like this:
ControlView {
// More definition follows
}
And you would use it like this:
property Component dateTumbler: DateTumblerView {}
Or:
Component {
id: dateTumbler
DateTumblerView {}
}
Or if you wanted to use it directly:
DateTumblerView {}
It's pretty much the same as when your code was just in one file. Anytime you do <Type> {}, you're inheriting that type and can set or add new properties, functions, and subcomponents. The difference is that it is in a separate file, has a specific name (the name of the file), and you can reuse that code as many times as you want.
For more details, see Defining Custom QML Types for Re-use.

Related

How to create custom local template object in qml?

In my qml file i have a lot of uniform objects with few differencies (id for example).
I want to use "Don't Repeat Yourself" principle
So i want create custom local template, which i'll can append with unique properties on using.
I know about creating separate .qml file, but this templates are too small for this mechanism (It's seems wired for me to create separate .qml file for red squares with 2px border)
Is there any meachanism for small templates in qml?
Qt 5.15.0 adds support for inline components. Here's the example from the docs:
import QtQuick 2.15
Item {
component LabeledImage: Column {
property alias source: image.source
property alias caption: text.text
Image {
id: image
width: 50
height: 50
}
Text {
id: text
font.bold: true
}
}
Row {
LabeledImage {
id: before
source: "before.png"
caption: "Before"
}
LabeledImage {
id: after
source: "after.png"
caption: "After"
}
}
property LabeledImage selectedImage: before
}

How to extend and style existing LitElements?

We want to work with components from https://github.com/ing-bank/lion and style them to our needs. Their repo advertises with the components being extensible and minimally styled. However, I cannot seem to figure out how to actually style them. We tried using style element in the parent component, but we cant seem to style these components properly.
Could you give me an example of how to extend a component?
update after answer by #niiyeboah
After a very nice answer by #niiyeboah, I created the following class:
import {css, customElement} from 'lit-element'
import {LionButton} from '#lion/button'
#customElement('my-custom-button')
class MyCustomButton extends LionButton {
static get styles() {
return [
super.styles,
css`
:host {
background-color: red;
}
`,
]
}
constructor() {
super()
}
}
However, now it just shows be the button completely unstyled, i.e. only the text. Does anyone know whats happening?
They provide an example of how to extend and style their components on this page.
For tabs, the code will look something like this:
import { css } from 'lit-element';
import { LionTabs } from '#lion/tabs';
export class MyTabs extends LionTabs {
static get styles() {
return [
super.styles,
css`
/* my stylings */
`
];
}
}
customElements.define('my-tabs', MyTabs);
The ING Lion team has a Slack channel: https://www.polymer-project.org/slack-invite
for support questions.
It is the #lion sub-channel in the Polymer Project Slack

QML, Combining multiple meshes into single entity

I am trying to create a customizable Qt3D component by merging three ConeMeshes into a single entity. The user must be able to interact with the custom entity, so I have added an ObjectPicker to the file. Normally, I would use a predefined scaled .obj file, but my manager wants the objects to be drawn directly by Qt.
The two meshes I want to combine are defined in a seperate qml file, so I can call it within my Scene3D.
Entity {
ObjectPicker {
id: combinedPicker
}
ConeMesh {
id: conemesh1
...
}
ConeMesh {
id: conemesh2
...
}
Transform {
id: conetransform1
}
Transform {
id: conetransform2
}
Entity {
components: [conemesh1, conetransform1, conemesh2, conetransform2, combinedPicker]
}
}
My approach for putting the meshes together is to enclose them as components in a separate Entity scope, as shown in the last line. But this approach only renders the last entry in the components array. Above, that would be conemesh2.
Previously I tried to create multiple Entity instances, and pass each one the id of the ObjectPicker,
Entity {
components: [conemesh1, conetransform1, combinedPicker]
}
Entity {
components: [conemesh2, conetransform2, combinedPicker]
}
But as per the documentation of ObjectPicker, the object picker is not meant to be shared by multiple components.
So my question is this: What is the correct approach when merging multiple meshes into one single mesh in Qml?
I solved the problem by "factoring" out the ObjectPicker element, effectivly making it a sibling of the mesh entities.
Entity {
components:
[conePicker]
Entity {
id: pipeTopEntity
components: [coneMeshTop, coneTransformTop, floorMaterialTop]
}
Entity {
id: pipeBodyEntity
components: [coneMeshBody, coneTransformBody, floorMaterialBody]
}
Entity {
id: pipeBotEntity
components: [ coneMeshBot, coneTransformBot, floorMaterialBot]
}
}

Clarity Datagrid Custom filter example

Does anyone have a complete example of a custom filter for the clarity datagrid? The custom filter documentation is lacking and I can't figure out how to get their example to work. Better yet, a stackblitz for the full datagrid demo would be amazing!
Hope this helps:
1) My Field model field.ts
export interface Field {
field_nbr: number;
fieldType: string;
dataType: string;
}
2) Utility file util-filters.ts -
import {ClrDatagridStringFilterInterface} from "#clr/angular";
//Models
import { Field } from '../models/field';
/**
* Class for filtering Field metadata in datagrids on filterType property of model
*/
export class FieldTypeFilter implements ClrDatagridStringFilterInterface<Field> {
accepts(field: Field, search: string):boolean {
return "" + field.fieldType == search
|| field.fieldType.toLowerCase().indexOf(search) >= 0;
}
}
3) model-component.html
<clr-datagrid [(clrDgSingleSelected)]="singleSelected" [clDgRowSelection]="false">
<clr-dg-column >
Field Type
<clr-dg-string-filter [clrDgStringFilter]="fieldTypeFilter"></clr-dg-string-filter>
</clr-dg-column>
<clr-dg-column ><ng-container *clrDgHideableColumn="{hidden: false}">Data Type</ng-container></clr-dg-column>
<clr-dg-placeholder>No matching fields found</clr-dg-placeholder>
<clr-dg-row *clrDgItems="let field of allFields" [clrDgItem]="field" (click)='openModal(field)'>
<clr-dg-cell>{{field.fieldType}}</clr-dg-cell>
<clr-dg-cell>{{field.dataType}}</clr-dg-cell>
</clr-dg-row>
</clr-datagrid>
4) model-component.ts
import { Component, OnInit, ViewChild } from '#angular/core';
import { NgIf } from '#angular/common';
import { Wizard } from "#clr/angular";
import { Observable } from 'rxjs';
//Models
import { Field } from '../models/field';
//Utilities
import { FieldTypeFilter } from "../utils/field-filters";
#Component({
selector: 'model',
templateUrl: './model.component.html',
providers: [],
styleUrls: ['../app.component.css']
})
export class ModelComponent {
private fieldTypeFilter = new FieldTypeFilter;
....
}
Edit 01/14/2022
Sorry, I moved some things around on stackblitz and we have updated the repo since this was written.
Here is where the custom filter lives for the demo: https://github.com/vmware/clarity/blob/angular/src/app/datagrid/utils/color-filter.ts
I'm not posting source code because there are 12 different files and some are pretty long (> 100 loc).
Here is a working reproduction of the full demo in the Clarity docs: https://stackblitz.com/edit/full-datagrid-demo
If you ever have questions about how a Clarity component works you can always dive into the source code for the demos we use for development and testing. Take a look here, I linked to the dev app we use for dev/testing so you know where I got the full datagrid code from. https://github.com/vmware/clarity/tree/master/src/dev/src/app

Dot symbol in "type" field of property definition operator

I am using Qt 5.2 and QtQuick 2.2.
In my project I have several modules that are placed in separated directories. My problem is that I can't use dot-separator in typename while defining properties.
For example:
MyRect.qml
import QtQuick 2.2
Rectangle {
id: root
property color rectColor: "white"
color: root.rectColor
}
MyRectInRect.qml
import QtQuick 2.2
import "./" as MyModule
Rectangle {
id: root
property MyModule.MyRect innerRect: MyModule.MyRect { }
// ^ error: Unexpected token `.'; Unexpected token `identifier'
}
I have searched for something that could explain this behavior in the manual, but looks like there is nothing about it there. I guess that dot symbol is not allowed to be used in "type" field of property definition. But is there any way to explicitly define, what component from which module should be used as a type? Cause there may be need of declaring properties with same typenames, but from different modules.
This is a known issue: QTBUG-10822

Resources