QML: How to implement signal handler of a child - qt

I'm editing a component in Qt Creator. It suggested me to split the component in UI and not UI parts. My components exposes 2 custom properties.
ComponentViewForm {
property string step: '0'
property string setStep: '0'
}
A TextInput inside the UI-Part is bound to step
It should set the property setStep in onAccepted handler.
First one is easy. The binding can be edited in UI-Editor directly
But how do I implement the signal-handler of the child?
I've implemented it directly in the UI.
TextInput {
id: step
text: parent.step
onAccepted:
{
parent.setStep = text
}
}
It works, but Qt-Creator rejects to open it in UI-mode any more.

You can export the TextInput from your ComponentViewForm. There's a small Export button in the Navigator tab in Qt Quick UI forms editor. Assume that the id of TextInput is stepInput, ComponentViewForm.ui.qml should have an alias property property alias stepInput: stepInput in source code after you click the Export button.
You can implement property binding and signal handlers in ComponentView.qml like this:
ComponentViewForm {
property string step: '0'
property string setStep: '0'
stepInput.text: step
stepInput.onAccepted:
{
setStep = stepInput.text;
}
}

Related

QQmlComponent initialization

i have an application which sets properties of Qml from C++, so far i was able to set property of any type. I am able to create QQmlComponent in C++ and set it to property.
But first i need to initialize component with its properties. I can do that with create/beginCreate and set properties. But i cant change created QObject back to QQmlComponent, therefor i cant set it to givent Component type property.
Is there some way how to conver QObject to QQmlComponent ? Or is there any other way to initialize QQmlComponent properties ?
Example, of what i want to achiev in C++, how it looks in qml
import QtQuick 2.3
Loader {
// property of type Component
sourceComponent: Text {
text: "property i want to intialize, this component can be in file"
}
}
Edit: I will clarify what im after. Suppose i have something like JSON given by user.
e.g:
{
"type":"Loader",
"sourceComponent":{
"type":"Text",
"text":"some property of property of type QQmlComponentProperty"
}
}
Then from C++ i create given items, problem is how to create QQmlComponent with user given properties.

How to close multiple dialog box using Angular

I have a running Angular 9 application and I have created custom dialog box. I have also used ComponentFactoryResolver to dynamically load the component.
My custom dialog box looks like:
So, when I click on close button, the dialog box closes.
As per the current implementation, if I open multiple dialog box on the screen, then I am able to close only last opened dialog box by clicking on close button.
My expected behavior is to close all the dialog box. Please help me on this
Stackblitz demo: https://stackblitz.com/edit/dialog-box-overlay
Note: In this stackblitz demo, one modal opens on the top of another modal as I have not modified the css. So, please focus on Modal name to get to know which modal is opened
Instead of assigning the created modal component to the services dcRef property you need to manage all of your modal components, i.e. in a list. Your service's open() method
open(component: Type<any>, modalName: string) {
const factory = this.componentFactoryResolver.resolveComponentFactory(DialogComponent);
this.dcRef = factory.create(this.injector);
...
return this.dcRef;
}
returns the component reference. You could manage this reference from the caller and pass it as an argument to your close() method. When all of the component refs are managed by the service you can also "batch close" all modals (see closeAll()):
#Injectable()
export class DialogService {
refs: ComponentRef<DialogComponent>[] = [];
constructor(private componentFactoryResolver: ComponentFactoryResolver,
private applicationRef: ApplicationRef,
private injector: Injector
) { }
open(component: Type<any>, modalName: string) {
const factory = this.componentFactoryResolver.resolveComponentFactory(DialogComponent);
var ref = factory.create(this.injector);
this.applicationRef.attachView(ref.hostView);
const domElement = (ref.hostView as EmbeddedViewRef<any>).rootNodes[0] as HTMLElement;
document.body.appendChild(domElement);
ref.changeDetectorRef.detectChanges();
ref.instance.open(component, modalName);
this.refs.push(ref);
return ref;
}
close(ref) {
this.applicationRef.detachView(ref.hostView);
ref.instance.close();
ref.destroy();
// Remove ref from a list managed by the service
var i = this.refs.indexOf(ref);
this.refs.splice(i, 1);
}
closeAll()
{
this.refs.forEach(r => this.close(r));
}
}
This is not tested and might need to be tuned, but you should get the idea. Instead of using the ComponentRef as a handle you can also create some custom object to prevent the caller of the modal to interact with the component directly.

How to detect if any of QML editable items in the root Item were edited?

I have an item of some type that consists of several QML editing controls:
Column {
id: inputItem
SpinBox {
}
TextInput {
}
ComboBox {
}
Button {
id: enableMeButton // this needs to be enabled if
text: "Apply" // anything was changed above
enabled: false
}
}
This item [Column as example] can be potentially inserted to some list view as "polymorphic" editing item so that we don't know beforehand what edit fields to handle (say we would want to move Apply outside). Or we want to use a common type with Apply to develop different editing delegates (which is the story here).
How can we detect that any of the data handled in this form was changed? Is there a generic way to do so or there is some trick to accomplish it?

QML Calendar : Programmatically call onClicked handler

My QML application is displaying a Calendar element.
When the selected date is changed (clicked), I need to update an other element (an image).
I have something like this:
Calendar {
id: calCalendar
onClicked: {
// update other QML element
}
}
It works fine when the user click with the mouse on the calendar: the other element (the image) is correctly updated.
My problem is initialization : when my app is started, the calendar displays the current date by default, and I'd like to programmatically call the onClicked handler, to make sure the image is up to date.
I don't know how to do that.
If you want to do something when a QML component is done initializing you can use the Component.onCompleted : slot.
Calendar {
id: calCalendar
onClicked: {
// update other QML element
}
Component.onCompleted: {
// Do stuff for initialization.
// you could do this here : calCalendar.Clicked()
// if you want to use the same code for initialization and for user input handling later on.
}
}
The point is the following : onXXX : { declares a slot to handle the singal XXX. Here the signal is Clicked. You can trigger the signal programmatically as you say, just by invoking it like a function. You'll need to know a valid overload for the arguments (if any).

How to check if qml component object (that is created dynamically) has been created?

I have a component that should be created dynamically.
Component {
id: myComponent
Rectangle {
id: letItBeRect
}
}
I want to create it dynamically (when some button clicked) in a function like this:
function loadComponent() {
myComponent.createObject(root); //root is some root component, doesn't matter
}
I have state for root component that depends on some letItBeRect property:
state: letItBeRect.visible ? "visible" : "hidden"
So the question is how do I check if letItBeRect has been created, so I could assign a proper value to "state" property of root component?
I get "ReferenceError: letItBeRect is not defined" so far, which is expected from this code snippet.
P.S. This is not the real code I have, because I don't want to put commercial code here. Thank you

Resources