Pass value from child QtQuck QML to main QML - qt

I have to pass some values from child QML open with component to main QML and use them to do something in main QML.
This is my two QML files:
I have mail.qml like this:
import QtQuick 2.10
import QtQuick.Window 2.10
import QtQuick.Controls 2.3
ApplicationWindow {
id: applicationWindow
property string selected_contact_account_str: String()
/* Contacts */
function createContacts() {
var component = Qt.createComponent("ContactList.qml");
console.log("Component Status:", component.status, component.errorString());
var window = component.createObject(applicationWindow, {"x": 0, "y": 0});
window.showFullScreen();
}
Icon {
id: contacts
anchors.top: parent.top
anchors.topMargin: 60
anchors.left: parent.left
anchors.leftMargin: 20
iconsize: 96
iconsource: "content/contacts_icon.png"
iconname: "Contacts"
fontsize: 14
MouseArea {
anchors.fill: parent
onClicked: createContacts()
}
}
/* End Contacts */
}
And an ContactList.qml with Button:
import QtQuick 2.10
import QtQuick.Controls 2.3
import QtQuick.Window 2.2
ApplicationWindow {
id: contactsList
Item {
Item {
id: appContainer
anchors.fill: parent
anchors.centerIn: parent
Button {
id: contact_select
text: qsTr("Select")
onClicked: {
// I want to pass value from here to main.qml
// store in selected_contact_account_str
// So I can use it in mail.qml
}
}
}
}
How can I do?

you can use signal and slot to do it.
In
ApplicationWindow
id: contactsList
signal sendmessage(var message)
.
.
.
onClicked: {
contactsList.sendmessage("test");
}
then in first file
function createContacts() {
window.sendmessage.connect(handleMessage)
}
function handleMessage(message){
}

Related

TableView QML Type onClicked event

I am currently using a TableView in my QML file. I would like to know which cell the user clicked.. There is a post here: https://forum.qt.io/topic/84284/tableview-onclicked-slot/2 which shows the onClicked code in the QML file. However, when i tried on my code it says invalid property name. My QML file code is:
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
import TransactionHistoryTableModel 1.0
import tech.siotgov.DataManager 1.0
import "../../components" as Components
import "../../utils/httpRequest.js" as HttpRequest
Rectangle {
id: root
objectName: "TransactionHistory"
color: "white"
property string pageTitle: "Transaction History"
ColumnLayout {
id: home
anchors.leftMargin: parent.width * 0.05
anchors.rightMargin: parent.width * 0.05
anchors.fill: parent
anchors.horizontalCenter: parent.horizontalCenter
Components.PageTitle {
title: pageTitle
}
Rectangle {
id: transactionHistoryDisplay
color: "white"
Layout.fillWidth: true
Layout.preferredHeight: parent.height - 100
Components.Table {
model: _transactionHistoryTableModelAPI
columnWidths: [0.4, 0.6]
onClicked: {
console.log(" click ")
console.log(color_string)
}
}
}
Item { //spacer
Layout.fillWidth: true
Layout.fillHeight: true
Rectangle {
anchors.fill: parent
color: "white"
}
}
}
Component.onCompleted: {
const locationId = DataManager.currentLocation.locationId;
const d = new Date()
d.setTime(d.getTime() - d.getTimezoneOffset()*60*1000);
const datetimeStamp = d.toISOString().split('.')[0]
_transactionHistoryTableModelAPI.resetTable(locationId);
HttpRequest.query(
"query { transactionsByLocation(fromDateTime:\"2019-01-01T07:54:34\", toDateTime:\"" + datetimeStamp + "\", location:" + locationId + ") { transactionId, datetime, items { transactionItemId }, transactionType {name}, location_1{locationName}, location_2{locationName} } }",
res => {
_transactionHistoryTableModelAPI.updateTable(res.data.transactionsByLocation);
})
}
}
The Table.qml file is:
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
TableView {
anchors.fill: parent
clip: true
property var columnWidths: [0.5, 0.5] // as fractions of parent width
// preferably overwrite this when using
columnWidthProvider: function (column) { return Math.max(parent.width * columnWidths[column], 1) }
delegate: Rectangle {
implicitHeight: text.implicitHeight
border.color: "#dddddd"
color: (heading==true)?"#dddddd":"white"
Text {
id: text
text: tabledata
width: parent.width
wrapMode: Text.Wrap
padding: 5
}
}
}
In a view you must set the MouseArea in the delegate and expose it through a signal from the root of the component:
Table.qml
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
TableView {
id: root
anchors.fill: parent
clip: true
signal clicked(int row, int column) // <---
property var columnWidths: [0.5, 0.5] // as fractions of parent width
// preferably overwrite this when using
columnWidthProvider: function (column) { return Math.max(parent.width * columnWidths[column], 1) }
delegate: Rectangle {
implicitHeight: text.implicitHeight
border.color: "#dddddd"
color: heading ? "#dddddd" : "white"
Text {
id: text
text: tabledata
width: parent.width
wrapMode: Text.Wrap
padding: 5
}
MouseArea{
anchors.fill: parent
onClicked: root.clicked(model.row, model.column) // <---
}
}
}
*.qml
// ...
Components.Table {
model: _transactionHistoryTableModelAPI
columnWidths: [0.4, 0.6]
onClicked: console.log(row, column)
}
// ...

How can I assign an ordering number to dynamically created component in qml?

My code (actually an official example) can draw markers and polylines on the point which I clicked. And I want that every marker has their own Text which represents its order. Text "1" for the first marker, and Text "2" for the second marker, for example. But markerCount(declared in componentCreation.js) for the Text does not increase, so all of the Text of the marker is "1" which is a default.
In the code, Rectangle which is MapQuickItem's child represents a marker, and it is dynamically created by createElements() (componentCreation.js). markerCount++ is implemented in Component.onCompleted.
The code is:
componentCreation.js
var arrayLines = []
var lineComplete = false
var markerCount = 1
function createElements(point) {
console.log(markerCount)
var componentMarker = Qt.createComponent("Marker.qml");
if (componentMarker.status === Component.Ready) {
var markerFirstCorner = componentMarker.createObject(map);
markerFirstCorner.coordinate = map.toCoordinate(point)
map.addMapItem(markerFirstCorner)
} else {
console.log("Marker not created")
}
var theLine
if (arrayLines.length === 0) {
createLine(point)
} else {
theLine = arrayLines[arrayLines.length-1]
theLine.mainPolyline.addCoordinate(map.toCoordinate(point))
}
}
function createLine(point){
var componentLine = Qt.createComponent("Line.qml")
if (componentLine.status === Component.Ready) {
var lineFirstCorner = componentLine.createObject(map);
lineFirstCorner.mainPolyline.addCoordinate(map.toCoordinate(point))
map.addMapItem(lineFirstCorner)
arrayLines.push(lineFirstCorner)
} else {
console.log("Line not created")
}
}
main.qml
import QtQuick 2.11
import QtQuick.Window 2.11
import QtLocation 5.11
import QtPositioning 5.8
import QtQuick.Controls 2.1
import "componentCreation.js" as MyScript
ApplicationWindow {
id: applicationWindow
visible: true
width: 640
height: 480
Plugin {
id: mapPlugin
name: "googlemaps"
}
Map {
id: map
anchors.fill: parent
zoomLevel: 12
plugin: mapPlugin
center: QtPositioning.coordinate(35.8926195, 128.6000172)
MouseArea{
id: mouseArea
anchors.fill: parent
z: 1
onClicked: {
console.log("Before creation : " + MyScript.markerCount)
var point = Qt.point(mouse.x, mouse.y)
console.log()
console.log("You clicked : " + map.toCoordinate(point))
MyScript.createElements(Qt.point(mouse.x,mouse.y))
}
}
}
}
Marker.qml
import QtQuick 2.0
import QtLocation 5.11
import "componentCreation.js" as MyScript
MapQuickItem {
property alias marker: marker
id: marker
sourceItem: Rectangle {
width: 50
height: 50
color: "transparent"
Image {
anchors.fill: parent
source: "images/drone.svg" // Ignore warnings from this
sourceSize: Qt.size(parent.width, parent.height)
}
Text {
anchors.fill: parent
text: { MyScript.markerCount }
}
Component.onCompleted: {
MyScript.markerCount++
console.log("markerCount: " + MyScript.markerCount)
}
}
opacity: 1.0
anchorPoint: Qt.point(sourceItem.width/2, sourceItem.height/2)
}
Line.qml
import QtQuick 2.0
import QtLocation 5.8
MapPolyline {
property alias mainPolyline: mainPolyline
id: mainPolyline
line.width: 3
line.color: 'black'
}
I'm new to Qt and Qml. I don't know why markerCount does not increase. Please tell me why or give me another way to order the markers.
Thank you for your help.
You are complicating yourself too much, in case you want to store a lot of information the correct thing is to use a model, in this case ListModel, and a view, in this case MapItemView, that has as a delegate the Marker, then use a property to save the index that it is obtained by using the count property of the model:
Marker.qml
import QtQuick 2.0
import QtLocation 5.11
MapQuickItem {
id: marker
property alias text: txt.text
sourceItem: Rectangle {
width: 50
height: 50
color: "transparent"
Image {
anchors.fill: parent
source: "images/drone.svg" // Ignore warnings from this
sourceSize: Qt.size(parent.width, parent.height)
}
Text {
id: txt
anchors.fill: parent
}
}
opacity: 1.0
anchorPoint: Qt.point(sourceItem.width/2, sourceItem.height/2)
}
main.qml
import QtQuick 2.11
import QtQuick.Window 2.11
import QtLocation 5.11
import QtPositioning 5.8
import QtQuick.Controls 2.1
ApplicationWindow {
id: applicationWindow
visible: true
width: 640
height: 480
Plugin {
id: mapPlugin
name: "googlemaps"
}
ListModel{
id: md
}
Map {
id: map
anchors.fill: parent
zoomLevel: 12
plugin: mapPlugin
center: QtPositioning.coordinate(35.8926195, 128.6000172)
MapItemView{
model: md
delegate: Marker{
text: title
coordinate: QtPositioning.coordinate(coords.latitude, coords.longitude)
}
}
Line{
id: li
}
MouseArea{
id: mouseArea
anchors.fill: parent
z: 1
onClicked: {
var point = Qt.point(mouse.x, mouse.y)
var coord = map.toCoordinate(point);
var text = md.count + 1;
md.append({"coords": coord, "title": text})
li.addCoordinate(coord)
}
}
}
}
Line.qml
import QtQuick 2.0
import QtLocation 5.8
MapPolyline {
id: mainPolyline
line.width: 3
line.color: 'black'
}

how to load child1.qml page on to main.qml page calling from another_child.qml page

In my MyHeader.qml cannot load the MyChild2.qml. How to load child qml page on to mmain.qml page calling from another child qml page as shown below.
TestProject Folder
qml Folder
Main.qml
MyChild1.qml
mainui Folder
MyHeader.qml
MyChild2.qml
import QtQuick 2.10
import QtQuick.Controls 2.2
import "."
// Main.qml
ApplicationWindow {
id: rootApp
Loader {
id: loaderPage
anchors.fill: parent
}
MyChild1 {
}
}
// MyChild1.qml
import QtQuick 2.10
import QtQuick.Controls 2.2
import "."
Page {
id: myItem1
anchors.fill: parent
MyHeader {
anchors.top: parent.top
}
}
// MyChild2.qml
import QtQuick 2.10
import QtQuick.Controls 2.2
import "."
Page {
id: myItem2
anchors.fill: parent
Rectangle {
anchors.fill: parent
color: "#000000"
}
}
// MyHeader.qml
import QtQuick 2.10
import QtQuick.Controls 2.2
import "."
Rectangle {
id: myHeader
width: parent.width
height: dp(30)
color: "lightblue"
Text {
id: loadQML
text: "Load QML"
color: "#000000"
font.pixelSize: dp(20)
MouseArea {
anchors.fill: parent
onClicked: {
myItem1.visible = false
loaderPage.source = "MyChild2.qml"
loaderPage.Top
}
}
}
}
Using the Loader and Connection I am getting Cannot assign to non-existent property "onPageChanged"
import QtQuick 2.10
import "mainui"
ApplicationWindow {
id: rootApp
signal pageChanged(int page);
Loader {
id:rootLoader
anchors.fill: parent
source: "mainui/Page1.qml"
Connections {
target: rootLoader.item
onPageChanged: {
switch(page)
{
case 1: rootLoader.source = "mainui/Page1.qml"; break;
case 2: rootLoader.source = "mainui/Page2.qml"; break;
}
}
}
}
} // APP
Due to scope limitation of Loader you cannot access items outside it. But you can notify the Loader to do some action. In the example below there are 2 components define a signal. The Loader connects this signal to a handler:
import QtQuick 2.9
import QtQuick.Window 2.2
Window {
id: win
width: 400
height: 400
title: "Test"
visible: true
Component {
id: page1
Rectangle {
signal pageChanged(int page);
anchors.fill: parent
color: "orange"
Text {
anchors.centerIn: parent
text: "PAGE 1\nClick to change"
horizontalAlignment: Text.AlignHCenter
}
MouseArea {
anchors.fill: parent
onClicked: {
pageChanged(2);
}
}
}
}
Component {
id: page2
Rectangle {
signal pageChanged(int page);
anchors.fill: parent
color: "lightblue"
Text {
anchors.centerIn: parent
text: "PAGE 2\nClick to change"
horizontalAlignment: Text.AlignHCenter
}
MouseArea {
anchors.fill: parent
onClicked: {
pageChanged(1);
}
}
}
}
Loader {
id: loader
anchors.fill: parent
sourceComponent: page1
Connections {
target: loader.item
onPageChanged: {
switch(page)
{
case 1: loader.sourceComponent = page1; break;
case 2: loader.sourceComponent = page2; break;
}
}
}
}
}

Adding TabButton dynamically to TabBar in QML

I am trying to add a tabButton to TabBar dynamically on pressing a button but i have spent a lot of time searching but i am not getting how to add, below is the code which i am working on :
MyTabButton.qml
import QtQuick 2.4
import QtQuick.Controls 2.2
Item
{
property int BtnWidth:0
property int BtnHeight:0
property string BtnText: ""
property bool isChecked : false
TabButton
{
id:tabBtn
text:BtnText
width:BtnWidth
height:BtnHeight
}
}
MainForm.qml
import QtQuick 2.4
import QtQuick.Controls 2.2
Rectangle
{
Button
{
id:button
width:100
height:100
anchors.top:parent.top
text:qStr("Add")
onClicked{
//How to add logic here to add tab in below tabBar.
}
}
TabBar
{
id:tabBar
anchors.top:button.bottom
width:500
height:500
}
}
Example:
import QtQuick 2.7
import QtQuick.Controls 2.0
ApplicationWindow {
id: window
width: 360
height: 630
visible: true
header: TabBar {
id: tabBar
}
Component {
id: tabButton
TabButton { }
}
Button {
text: "Add"
anchors.centerIn: parent
onClicked: {
var tab = tabButton.createObject(tabBar, {text: "Tab " + tabBar.count})
tabBar.addItem(tab)
}
}
}
You need to have something like a Component that is a TabButton. Your file MyTabButton.qml won't result in a TabButton, but instead an Item containing a TabButton, but with this, your TabBar does not know what to do.
So your file will need to have TabButton as root element
//MyTabButton.qml
import QtQuick 2.4
import QtQuick.Controls 2.2
TabButton
{
id: tabBtn
// customize as you like
}
Then you create a Component of this in your file where you want to use it. (e.g. main.qml)
import QtQuick 2.4
import QtQuick.Controls 2.0
ApplicationWindow {
width: 800
height: 600
visible: true
TabBar {
id: tabBar
width: 800
height: 50
}
// The component is like a factory for MyTabButtons now.
// Use myTabButton.createObject(parent, jsobject-with-property-assignments) to create instances.
Component {
id: myTabButton
MyTabButton {
/// EDIT ACCORDING TO YOUR COMMENTS ***
Connections {
target: tabBar
onCurrentIndexChanged: doSomething()
}
/// EDIT OVER
}
}
Button {
anchors.centerIn: parent
// Create a object out of the component, and add it to the container
onClicked: tabBar.addItem(myTabButton.createObject(tabBar /*, { object to set properties }*/))
}
}
TabBar inherits Container, which has addItem().
Try it in Window
Row {
anchors.fill: parent
TabBar {
id: tabBar
currentIndex: 0
width: parent.width - addButton.width
TabButton { text: "TabButton" }
}
Component {
id: tabButton
TabButton { text: "TabButton" }
}
Button {
id: addButton
text: "+"
flat: true
onClicked: {
tabBar.addItem(tabButton.createObject(tabBar))
console.log("added:", tabBar.itemAt(tabBar.count - 1))
}
}
}

How to use mouseclick area from loaded Form in qml?

below is my code snippet where i'm loading qml ui using dynamic object creation method now i have to implement mousearea which reside in loaded file, can anyone help me to do this
Qt.createQmlObject(" import QtQuick 2.0
Loader {
id: pageLoader
source: '/HomeScreenForm.ui.qml'
anchors.fill: parent
anchors.rightMargin: 0
anchors.leftMargin: 0
anchors.bottomMargin: parent
anchors.topMargin: parent
}
", rectangle7)
Create custom item contains MouseArea. To make the area accessible from outside you can use alias, for example:
MyItem.qml
import QtQuick 2.7
Rectangle {
id: root
color: "yellow"
property alias area: mouseArea
MouseArea {
id: mouseArea
anchors.fill: parent
}
Text {
anchors.centerIn: parent
text: "Click me!"
}
}
And then you can create it dynamically:
import QtQuick 2.7
import QtQuick.Window 2.0
Window {
id: mainWindow
width: 600
height: 600
visible: true
Component.onCompleted: {
var component = Qt.createComponent("MyItem.qml");
if (component.status === Component.Ready) {
var obj = component.createObject(mainWindow);
obj.width = 200;
obj.height = 200;
obj.anchors.centerIn = mainWindow.contentItem;
obj.area.onPressed.connect(
function(mouse){
console.log("pressed at (", mouse.x,",",mouse.y,")")
});
}
}
}
Another way is using Connections, as #derM already noticed.

Resources