Rectangle with onEditingFinished
-
@gabor53
If you define your notification message in a separate QML file, then you shouldn't define it as aComponentin that file. E.g. you would defineMessages.qmlas:Rectangle { height: 20 width: 200 property alias text: msg.text Text { id: msg anchors.fill: parent } }Then, the dynamic object instantiation consists of two step:
- Dynamically create a component, e.g.
msgComponentfromMessages.qmlusingQt.CreateComponent() - Dynamically create the object from that component using
msgComponent.createObject()
http://doc.qt.io/qt-5/qtqml-javascript-dynamicobjectcreation.html
I guess this rather tedious approach is due to the declarative nature of QML?
To save you the trouble, you could put this dynamic creation code inside a JS source file e.g. "code.js" which you would then import first likeimport "code.js" as JsThe JS code could look as follows:
function createMsg(parent, args) { var msgComp = Qt.CreateComponent("Message.qml") var msg = msgComp.createObject(parent, args); return msg }If you rather not recreate the component all over again, you could also do something like:
var msgComp //global JS variable <-- usually not recommended though function createMsg(parent, args) { if (msgComp!==undefined) msgComp = Qt.CreateComponent("Message.qml") var msg = msgComp.createObject(parent, args); return msg }Then in your QML code, simply call this function whenever you need as follows:
onEditingFinished: { if (addName.text === "") { var popup = Js.createMsg(yourPageId, {text: "Enter the name."}) } }The possibilities are plenty!
@Diracsbracket
Thank you for the detailed explanation. I chose to create the Js file (code.js) and it looks like this:function createMsg(parent, args) { var msgComp = Qt.createComponent("Messages.qml") var msg = msg.Comp.createObject(parent, args) return msg }I changed the Messages.qml:
import QtQuick 2.0 import QtQuick 2.2 import VPlayApps 1.0 Rectangle { id: notificationSquare height: dp(30) anchors.top: addName.bottom anchors.left: addName.left anchors.topMargin: 20 color: transparent width: dp(250) border.color: "#ff0000" border.width: 2 property alias text: msg.text Text { id: msg font.bold: true horizontalAlignment: Text.AlignHCenter color: "red" font.pointSize: 20 anchors.fill: notificationSquare anchors.horizontalCenter: notificationSquare.horizontalCenter anchors.verticalCenter: notificationSquare.verticalCenter } }AddaFriendP1.qml has id: add1 and the relevant code:
onEditingFinished: { if (addName.text == "") { var popup = Js.createMsg(add1, { text: "Enter the Friend's name." }) } }I have no error message, but the warning message doesn't pop up either. Did I miss something?
Thank you for your help. - Dynamically create a component, e.g.
-
@Diracsbracket
Thank you for the detailed explanation. I chose to create the Js file (code.js) and it looks like this:function createMsg(parent, args) { var msgComp = Qt.createComponent("Messages.qml") var msg = msg.Comp.createObject(parent, args) return msg }I changed the Messages.qml:
import QtQuick 2.0 import QtQuick 2.2 import VPlayApps 1.0 Rectangle { id: notificationSquare height: dp(30) anchors.top: addName.bottom anchors.left: addName.left anchors.topMargin: 20 color: transparent width: dp(250) border.color: "#ff0000" border.width: 2 property alias text: msg.text Text { id: msg font.bold: true horizontalAlignment: Text.AlignHCenter color: "red" font.pointSize: 20 anchors.fill: notificationSquare anchors.horizontalCenter: notificationSquare.horizontalCenter anchors.verticalCenter: notificationSquare.verticalCenter } }AddaFriendP1.qml has id: add1 and the relevant code:
onEditingFinished: { if (addName.text == "") { var popup = Js.createMsg(add1, { text: "Enter the Friend's name." }) } }I have no error message, but the warning message doesn't pop up either. Did I miss something?
Thank you for your help.@gabor53 said in Rectangle with onEditingFinished:
var msg = msg.Comp.createObject(parent, args)
Must be
var msg = msgComp.createObject(parent, args)Also, if a component is to be reusable, it is usually better to use
parentproperties to determine its size/anchoring rather than to hard-code some element's id.Rectangle { id: notificationSquare ... anchors.top: parent.bottom //<- should work if parent does not have clip: true? //addName.bottom anchors.left: parent.left //addName.left }As mentioned in the comments above, anchoring the
topof a child to thebottomproperty of itsparentworks if the parent'sclipproperty isfalse(which is the default). Ifclipis set totruethe child will not be visible with the above anchoring.color: transparent
Did that not generate an error in your
Application Outputwindow?
There is no colortransparent-> should be"transparent"between quotes. -
@gabor53 said in Rectangle with onEditingFinished:
var msg = msg.Comp.createObject(parent, args)
Must be
var msg = msgComp.createObject(parent, args)Also, if a component is to be reusable, it is usually better to use
parentproperties to determine its size/anchoring rather than to hard-code some element's id.Rectangle { id: notificationSquare ... anchors.top: parent.bottom //<- should work if parent does not have clip: true? //addName.bottom anchors.left: parent.left //addName.left }As mentioned in the comments above, anchoring the
topof a child to thebottomproperty of itsparentworks if the parent'sclipproperty isfalse(which is the default). Ifclipis set totruethe child will not be visible with the above anchoring.color: transparent
Did that not generate an error in your
Application Outputwindow?
There is no colortransparent-> should be"transparent"between quotes.@Diracsbracket
There was no error message at all. -
@Diracsbracket
There was no error message at all.@gabor53 said in Rectangle with onEditingFinished:
There was no error message at all.
There was no error message at all in the
Application outputview when you tried to run it?

If those errors really are not reported, then you really should solve that problem first and find out why, but I suspect you may only have been looking at the
Compile Outputview or so. -
@gabor53 said in Rectangle with onEditingFinished:
There was no error message at all.
There was no error message at all in the
Application outputview when you tried to run it?

If those errors really are not reported, then you really should solve that problem first and find out why, but I suspect you may only have been looking at the
Compile Outputview or so.Hi @Diracsbracket ,
I fixed everything you highlighted and you are right, I focused on the compile output. In spite of the corrections it still doesn't display the rectangle and the text. Here are my changes:var msgComp = Qt.createComponent("Messages.qml") var msg = msgComp.createObject(parent, args) onEditingFinished: { if (addName.text === "") { var popup = Js.createMsg(add1, { text: "Enter the Friend's name." }) Rectangle { id: notificationSquare height: dp(30) anchors.top: parent.bottom anchors.left: parent.left anchors.topMargin: 20 color: "transparent"It seems correct but it is not working. Thank you for your help.
-
Hi @Diracsbracket ,
I fixed everything you highlighted and you are right, I focused on the compile output. In spite of the corrections it still doesn't display the rectangle and the text. Here are my changes:var msgComp = Qt.createComponent("Messages.qml") var msg = msgComp.createObject(parent, args) onEditingFinished: { if (addName.text === "") { var popup = Js.createMsg(add1, { text: "Enter the Friend's name." }) Rectangle { id: notificationSquare height: dp(30) anchors.top: parent.bottom anchors.left: parent.left anchors.topMargin: 20 color: "transparent"It seems correct but it is not working. Thank you for your help.
@gabor53
I think it's best if you try the following minimal test program, run it and compare it with what you have:main.qml:import QtQuick 2.11 import QtQuick.Window 2.11 import QtQuick.Controls 2.4 import "code.js" as Js ApplicationWindow { id: window visible: true width: 640 height: 480 title: qsTr("Hello World") Rectangle { id: root color: "lightblue" anchors.fill: parent focus: false Text { id: id text: "ID:" x: 30 y: 30 font.pointSize: 16 focus: false } TextField { id: addName anchors.top: id.bottom x: 30 anchors.margins: 30 maximumLength: 85 placeholderText: "Add Name" focus: true property Message msg onLengthChanged: { if (msg && length>0) msg.destroy() } onEditingFinished: { if (length === 0) msg = Js.createMsg(addName, {"text": "Enter the Friend's name."}) else { focus = false console.debug("OK") } } } }code.jsfunction createMsg(parent, args) { var msgComp = Qt.createComponent("Message.qml") var msg = msgComp.createObject(parent, args) return msg } -
@gabor53
I think it's best if you try the following minimal test program, run it and compare it with what you have:main.qml:import QtQuick 2.11 import QtQuick.Window 2.11 import QtQuick.Controls 2.4 import "code.js" as Js ApplicationWindow { id: window visible: true width: 640 height: 480 title: qsTr("Hello World") Rectangle { id: root color: "lightblue" anchors.fill: parent focus: false Text { id: id text: "ID:" x: 30 y: 30 font.pointSize: 16 focus: false } TextField { id: addName anchors.top: id.bottom x: 30 anchors.margins: 30 maximumLength: 85 placeholderText: "Add Name" focus: true property Message msg onLengthChanged: { if (msg && length>0) msg.destroy() } onEditingFinished: { if (length === 0) msg = Js.createMsg(addName, {"text": "Enter the Friend's name."}) else { focus = false console.debug("OK") } } } }code.jsfunction createMsg(parent, args) { var msgComp = Qt.createComponent("Message.qml") var msg = msgComp.createObject(parent, args) return msg }@Diracsbracket
Sorry for the late response. I needed to buy a new computer and I am still setting it up. -
@Diracsbracket
Sorry for the late response. I needed to buy a new computer and I am still setting it up.@gabor53 said in Rectangle with onEditingFinished:
I needed to buy a new computer and I am still setting it up.
I went through the same routine not so very long ago. Good luck!
-
@gabor53 said in Rectangle with onEditingFinished:
I needed to buy a new computer and I am still setting it up.
I went through the same routine not so very long ago. Good luck!
@Diracsbracket
Thank you. Now it seems to be working (both the new computer and the program).
I ended up with another issue:
To make Messages reusable I changed the anchoring from addName to parent. But addName is a child of addFriend1 so it is not aligned with addName. How can I tell the Rectangle from Messages in addFriend1 that the parent now is addName?
Thank you. -
@gabor53
I think it's best if you try the following minimal test program, run it and compare it with what you have:main.qml:import QtQuick 2.11 import QtQuick.Window 2.11 import QtQuick.Controls 2.4 import "code.js" as Js ApplicationWindow { id: window visible: true width: 640 height: 480 title: qsTr("Hello World") Rectangle { id: root color: "lightblue" anchors.fill: parent focus: false Text { id: id text: "ID:" x: 30 y: 30 font.pointSize: 16 focus: false } TextField { id: addName anchors.top: id.bottom x: 30 anchors.margins: 30 maximumLength: 85 placeholderText: "Add Name" focus: true property Message msg onLengthChanged: { if (msg && length>0) msg.destroy() } onEditingFinished: { if (length === 0) msg = Js.createMsg(addName, {"text": "Enter the Friend's name."}) else { focus = false console.debug("OK") } } } }code.jsfunction createMsg(parent, args) { var msgComp = Qt.createComponent("Message.qml") var msg = msgComp.createObject(parent, args) return msg }@gabor53
Don't you pass the desired parent object at object creation time? Like this:function createMsg(parent, args) { var msgComp = Qt.createComponent("Message.qml") var msg = msgComp.createObject(parent, args) return msg } -
@gabor53
Don't you pass the desired parent object at object creation time? Like this:function createMsg(parent, args) { var msgComp = Qt.createComponent("Message.qml") var msg = msgComp.createObject(parent, args) return msg }@Diracsbracket
I do. And the rectangle and the text is in the the top left corner. -
@Diracsbracket
I do. And the rectangle and the text is in the the top left corner.@gabor53
Show your result and your anchoring. They must be wrong.Using the test code as above (with a slight modification to destroy the message) I get this:
Rectangle { id: root color: "lightblue" anchors.fill: parent focus: false Text { id: id text: "ID:" x: 30 y: 30 font.pointSize: 16 focus: false } TextField { id: addName anchors.top: id.bottom x: 30 anchors.margins: 30 maximumLength: 85 placeholderText: "Add Name" focus: true //validator: RegExpValidator {regExp: /^[a-zA-Z ]{2,30}$/} property Message msg onLengthChanged: { if (msg && length>0) msg.destroy() } onEditingFinished: { if (length === 0) msg = Js.createMsg(addName, {"text": "Enter the Friend's name."}) else { focus = false console.debug("OK") } } } }
where
Messages.qmlisimport QtQuick 2.11 Rectangle { id: notificationSquare height: 30 anchors.top: parent.bottom anchors.left: parent.left anchors.topMargin: 20 color: "transparent" width: 250 border.color: "#ff0000" border.width: 2 property alias text: msg.text function destroy() { this.destroy() } Text { id: msg font.bold: true horizontalAlignment: Text.AlignHCenter color: "red" font.pointSize: 12 anchors.fill: parent anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter } } -
@gabor53
Show your result and your anchoring. They must be wrong.Using the test code as above (with a slight modification to destroy the message) I get this:
Rectangle { id: root color: "lightblue" anchors.fill: parent focus: false Text { id: id text: "ID:" x: 30 y: 30 font.pointSize: 16 focus: false } TextField { id: addName anchors.top: id.bottom x: 30 anchors.margins: 30 maximumLength: 85 placeholderText: "Add Name" focus: true //validator: RegExpValidator {regExp: /^[a-zA-Z ]{2,30}$/} property Message msg onLengthChanged: { if (msg && length>0) msg.destroy() } onEditingFinished: { if (length === 0) msg = Js.createMsg(addName, {"text": "Enter the Friend's name."}) else { focus = false console.debug("OK") } } } }
where
Messages.qmlisimport QtQuick 2.11 Rectangle { id: notificationSquare height: 30 anchors.top: parent.bottom anchors.left: parent.left anchors.topMargin: 20 color: "transparent" width: 250 border.color: "#ff0000" border.width: 2 property alias text: msg.text function destroy() { this.destroy() } Text { id: msg font.bold: true horizontalAlignment: Text.AlignHCenter color: "red" font.pointSize: 12 anchors.fill: parent anchors.horizontalCenter: parent.horizontalCenter anchors.verticalCenter: parent.verticalCenter } }@Diracsbracket
I figured out what I did incorrectly. Somehow I deleted the root rectangle.
Thank you for your detailed explanations. I learnt a lot.