Custom QML type. Expose children methods.
-
Hello everyone.
I want to create a custom QML type defined in a
MyTextField.qml
file.This type is Item with a Label and a TextField like:
Item { id: control Label { } TextField{ } }
I want to be able to use all the signals and properties of the TextField child from my custom type.
Like :
MyTextField { onEditingFinished: { //Do this } text: "testing" }
I can use alias properties and signals to bind the custom type to its children's properties. Also, I can expose the children as a property of the custom type.
But is there a recommended method for this?
I do not want to expose the child component, and creating aliases for all the properties is cumbersome.Many thanks for your help.
-
If you want to use all the properties and signals, either expose the child with an alias or make it a root component.
In your case I think that making it a root component is possible if you tweak a few things.
TextField { Label {} }
As far as I know there is no recommended way for this.
-
Thanks, this is a better method. If it is not much to ask, how I position the label on top of the textfield?
So MyTextField type is a Label with a description text and a TextField under this text. -
@Mesrine If you are referring to the layers. If the Label is the child of TextField it should automatically be drawn on top of it. So no additional intervention needed.
You can read more about it here:
https://doc.qt.io/qt-6/qml-qtquick-item.html#z-propP.S. Not sure if you need this for having a placeholder or not. But if yes, then TextField has already a property called placeholderText that does that job.
-
@Marko-Stanke
I want a description on top(y axis not z) of the textfield apart from the PlaceholderText. It is kind of working using
https://doc.qt.io/qt-6/qml-qtquick-controls-control.html#control-layout
like :import QtQuick import QtQuick.Controls import QtQuick.Templates as T import QtQrDec T.TextField { id: control property alias description: label_.text property alias labelfont: label_.font property bool qrfill:false signal fillqr(); implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset || Math.max(contentWidth, placeholder.implicitWidth) + leftPadding + rightPadding,label_.implicitWidth) implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, contentHeight + topPadding + bottomPadding, placeholder.implicitHeight + topPadding + bottomPadding) selectByMouse:true color:CustomStyle.frontColor1 placeholderTextColor:CustomStyle.midColor1 topPadding: label_.height PlaceholderText { id: placeholder x: control.leftPadding y: control.topPadding width: control.width - (control.leftPadding + control.rightPadding)-((qrscan.visible)?qrscan.width:0)-2*bckrect.border.width height: control.height - (control.topPadding + control.bottomPadding) text: control.placeholderText font: control.font color: control.placeholderTextColor verticalAlignment: control.verticalAlignment visible: !control.length && !control.preeditText && (!control.activeFocus || control.horizontalAlignment !== Qt.AlignHCenter) elide: Text.ElideRight renderType: control.renderType } Rectangle { id:qrscan implicitWidth: font.pixelSize implicitHeight: font.pixelSize anchors.left: placeholder.right anchors.verticalCenter: placeholder.verticalCenter color: "transparent" visible: control.qrfill&&!control.text&&control.enabled ShaderEffect { id: shader property var src: qrscan; property color fcolor:CustomStyle.frontColor2 property var pixelStep: Qt.vector2d(1/src.width, 1/src.height) fragmentShader: "qrc:/esterVtech.com/imports/MyDesigns/frag/qrscanner.frag.qsb" anchors.fill: qrscan } MouseArea { anchors.fill: qrscan onClicked: { control.fillqr(); } } } background: Item{ MyLabel { id:label_ elide: Text.ElideRight width:control.width } Rectangle { id: bckrect y:control.topPadding width:parent.width height:parent.height-label_.height radius:Math.min(bckrect.width,bckrect.height)*0.12 border.width: 1 // TextControlBorderThemeThickness border.color: !control.enabled ? CustomStyle.midColor1 : control.activeFocus ? CustomStyle.frontColor2 : control.hovered ? CustomStyle.frontColor1 : CustomStyle.frontColor3 color: control.enabled ? CustomStyle.backColor1 : CustomStyle.midColor1 } } }
I am putting the label as a child of the background property of the Textfield.
-
@Mesrine I understand.
Anchors is best for such sorts of things.
TextField { id: textField Label { anchors { top: textField.top topMargin: - (height / 2) } } }
It is a bit "dirty" to use - values. But if you don't use clipping this will work just fine.