attach MouseArea to MapParameter - qml

i want to display geojson file on maps and make these shapes clickable to show more details about a building for example.
what i get is just a coordinate ... i need to get geojson object of building clicked
Map {
id: map
anchors.fill: parent
plugin: Plugin {
name: "mapboxgl"
PluginParameter {
name: "mapboxgl.access_token"
value:"sk.eyJ1IjoiYWxub29yLXNjaG9vbCIsImEiOiJjbGF1cmd0YTEwOWNoM3ByNjdxaW0yZXZiIn0.-RGpdTPTSBqrUGc65oLPNQ"
}
MouseArea {
acceptedButtons: Qt.LeftButton | Qt.RightButton
anchors.fill: parent
onClicked: {
mouse.accepted=true
if (mouse.button == Qt.LeftButton) {
var coord = map.toCoordinate(Qt.point(mouse.x,mouse.y));
console.log(coord.latitude, coord.longitude)
console.log(JSON.stringify(mouse) )
} else {
}
}
}
DynamicParameter {
type: "source"
property var name: "buildingSource"
property var sourceType: "geojson"
property var data: ":building.json"
}
DynamicParameter {
type: "layer"
property var name: "buildinLayer"
property var layerType: "fill"
property var source: "buildingSource"
}
DynamicParameter {
type: "paint"
property var layer: "buildinLayer"
property var fillColor: "#bbb"
}

Related

QML connect signal from the main component to the child components

I have a Qt application that calls qt_update_values() to the main QML component. I want to send the new values to a specific delegate. How do I connect update_values() from the main component to be received by a specific child component, which is defined in another qml?
I have tried defining Connections in the child, but I am not sure what target I need to define...
In the main.qml i have something similar to this:
...
signal update_values(new_values)
function qt_update_values(newValues){
update_values(newValues);
}
Repeater {
id:idRepeater
model: 3
Rectangle {
id:example
Text{ text: "hello"}
...
AnotherComponent {name: "name", othervariables: "others"}
}
}
...
Then on AnotherComponent.qml i have:
...
signal update_values_child(new_values)
function onUpdate_values(newValues){
textid = newValues;
}
Text{ id:textid}
...
You don't connect from the parent to the main, but the other way around like this:
...
id: idOfTheParent // <=== THIS IS IMPORTANT
signal update_values(new_values)
function qt_update_values(newValues){
update_values(newValues);
}
Repeater {
id:idRepeater
model: 3
Rectangle {
id:example
Text{ text: "hello"}
...
AnotherComponent {
id: idOfAnotherComponent // This ID is only available in the
// scope of the Component
// that will be instantiated by the
// Repeater, i.e. children of the Rectangle
name: "name"
othervariables: "others"
}
Connections {
target: idOfTheParent
onUpdate_values: idOfAnotherComponent.dosomethingWith(new_values)
}
}
}
...
You could also use signal.connect() to add new connections
Repeater {
model: 10
delegate: Item { ... }
onItemAdded: {
idOfTheParent.update_values.connect(function() { // do what you want })
}
}
But if it is only broadcasting of a new value, the declarative way would be, to have properties in your delegate, and bind them to the properties that held the changeing values:
...
id: idOfTheParent
property var valueThatWillChange
Repeater {
model: 10
delegate: Item {
property int valueThatShallChangeToo: idOfTheParent.valueThatWillChange
}
}
...
To have all of it with different signals ofc. is possible:
For the Connections-solution the simplest thing is to call doSomething only if it is the right delegate instance:
// in the delegate
Connections {
target: idOfTheParent
onValue1Updated: if (index === 1) doYourStuff()
onValue2Updated: if (index === 2) doYourStuff()
onValue...
}
But this is easier with the second method:
id: idOfTheParent
Repeater {
model: 10
delegate: SomeItem {
function doSomething() { console.log(index, 'does something')
}
onItemAdded: {
idOfTheParent['value' + index + 'Updated'].connect(item.doSomething)
}
onItemRemoved: {
idOfTheParent['value' + index + 'Updated'].disconnect(item.doSomething)
}
}

Accessing ListItemComponents on the run

right now I'm trying to create a ListView which loads the dataModel using a custom QML. Here's the snippet of my code:
ListView {
id: firstPageListView
visible: false
dataModel: firstPageDataModel
layout: GridListLayout {
columnCount: 1
cellAspectRatio: 2.0
headerMode: ListHeaderMode.Standard
verticalCellSpacing: 10
}
listItemComponents: [
ListItemComponent {
//custom qml that will be used
ThumbNote {
title: ListItemData.title
text: ListItemData.text
imageSource: ListItemData.image
listmode: true //list mode
date: ListItemData.date
}
}
]
}
I want to create a button that will change the listmode property of each component into false. By doing so, the object will invoke a function that set in the onListModeChanged() of the ThumbNote QML.
Sorry for my poor english, any help would be appreciated. :)
Perhaps you might consider adding a property to the ListView and binding the ThumbNotes' properties to it.
E.g.:
ListView {
id: firstPageListView
visible: true
dataModel: firstPageDataModel
property bool listMode: true
...
listItemComponents: [
ListItemComponent {
//custom qml that will be used
ThumbNote {
title: ListItemData.title
text: ListItemData.text
imageSource: ListItemData.image
listmode: firstPageListView.listMode
date: ListItemData.date
}
}
]
}
Button {
onClicked: {
firstPageListView.listMode = false;
}
}

access context property from listview checkboxitem when onchechchanged

my qml:
if i create a button and call " _model.writeapp(appname);" from its click event it works fine, but not from the listview checkbox oncheckedchanged event
context is defined
Container {
ListView {
id: listid
dataModel: _model
function getAppName() {
return (_model.readApp());
}
function writeappName(appname) {
_model.writeapp(appname);
}
//! [1]
listItemComponents: [
ListItemComponent {
id: listcomp
type: "item"
Container {
id: conchk
CheckBox {
id: chkbx
text: ListItemData.appname
onCheckedChanged: {
console.log("checked")
if (checked) {
//have to call _model.writeapp(appname);
chkbx.ListItem.view.writeappName("hi")
}
}
}
}
}
]
}
}
Try changing this:
chkbx.ListItem.view.writeappName("hi")
To this:
conchk.ListItem.view.writeappName("hi")

Invocation from function in Blackberrry 10 qml?

I have invoked invite to BBM while clicking a button in qml,but i need to send the invitation for the contacts how to do this?my code
Button {
text: "Invite"
onClicked: {
invokeQuery.uri = "pin:210000A"
invokeQuery.updateQuery();
}
attachedObjects: [
Invocation {
id: invokeShare
query: InvokeQuery {
id: invokeQuery
}
onArmed: {
trigger("bb.action.INVITEBBM");
}
}
]
}
Can anyone send me some solutions to solve this.?
Thanks
Invocation query is immutable object which means that values in the query are not dynamic. If you want to update query in dynamic you need to do it via control signals or variables.
For example, you have a component called Inviter with the pin property exposed:
import bb.cascades 1.0
Container {
property string pin
Button {
text: "Invite to BBM"
onClicked: {
query.uri = "pin:" + pin
invoke.trigger("bb.action.INVITEBBM")
}
}
attachedObjects: [
Invocation {
id: invoke
query: InvokeQuery {
id: query
invokeTargetId: "sys.bbm.sharehandler"
onQueryChanged: {
invoke.query.updateQuery()
}
}
}
]
}
Then you can use it this way:
import bb.cascades 1.0
Page {
Container {
layout: DockLayout {
}
TextArea {
id: pinEditor
hintText: "Enter PIN to invite"
onTextChanged: {
inviter.pin = text
}
input.submitKey: SubmitKey.Send
}
Inviter {
id: inviter
horizontalAlignment: HorizontalAlignment.Center
verticalAlignment: VerticalAlignment.Center
}
}
}
Also, don't forget to enable "Blackberry Messenger" permission in your bar-descriptor.xml and add following libraries to your .pro file:
LIBS += -lbbplatformbbm
LIBS += -lbbsystem

How to access the outer components from listitemcomponents in listview bb10 qml?

I am not able to access the Datasource id from inside of the ListItemComponent. Can anyone help me in regards to this?
ListItemComponent {
type: "item"
Container {
id: listviewcontainer
Container {
preferredWidth: 768
layout: StackLayout {
orientation: LayoutOrientation.LeftToRight
}
CustomImageView {
leftPadding: 10
rightPadding: 10
url: ListItemData.from_image
horizontalAlignment: HorizontalAlignment.Left
verticalAlignment: VerticalAlignment.Center
}
Container {
preferredWidth: 538
layout: StackLayout {
orientation: LayoutOrientation.TopToBottom
}
Container {
layout: StackLayout {
orientation: LayoutOrientation.LeftToRight
}
Label {
text: ListItemData.from
textStyle {
base: SystemDefaults.TextStyles.TitleText
color: Color.create("#2db6ff")
}
}
ImageView {
imageSource: "asset:///Home/img.png"
verticalAlignment: VerticalAlignment.Center
}
}//Container
Label {
text: ListItemData.message
multiline: true
textStyle {
base: SystemDefaults.TextStyles.SubtitleText
}
content {
flags: TextContentFlag.Emoticons
}
}
Label {
id: time
text: ListItemData.time
textStyle {
base: SystemDefaults.TextStyles.SmallText
color: Color.create("#666666")
}
}
}//Container
ImageButton {
id: delete_btn
defaultImageSource: "asset:///Icon/delete.png"
pressedImageSource: "asset:///Icon/delete.png"
verticalAlignment: VerticalAlignment.Center
horizontalAlignment: HorizontalAlignment.Right
onClicked: {
deleteMessage(ListItemData.tid, ListItemData.uid);
}
function deleteMessage(tid, uid) {
var request = new XMLHttpRequest()
request.onreadystatechange = function() {
if (request.readyState == 4) {
var mResponse = request.responseText
mResponse = JSON.parse(mResponse)
var mResponseStatus = mResponse.response[0].receive.status;
var mMsg = mResponse.response[0].receive.message;
if (mResponseStatus == 1) {
msg_DataSource.source = "newurl.com" // This line not works here..
msg_DataSource.load(); // This line not works here..
} else if (mResponseStatus == 0) {
}
}
}// end function
request.open("GET", "myurl.com", true);
request.send();
}// deleteMessage
}//ImageButton
}//Container
}//Container
}//ListItemComponent
Here am not able to work out the following two lines
msg_DataSource.source = "newurl.com"
msg_DataSource.load();
I have tried like below but this also not working
listviewcontainer.ListItem.view.dataModel.message_DataSource.source = "myurl.com";
listviewcontainer.ListItem.view.dataModel.message_DataSource.load();
or this
listviewcontainer.ListItem.view.dataModel.source = "myurl.com";
listviewcontainer.ListItem.view.dataModel.load();
Another simplest way to store the object to global variable using the following code which works fine with me.
onCreationCompleted: {
Qt.tabbedPane = tabbedPane;
Qt.homeTab = homeTab;
}
Here I stored tabbedPane in global variable Qt.tabbedPane on page creation Completed.Now I able to access it from ListItemComponent using Qt.tabbedPane.
Hope it helps.
The simplest way to make the data model accessible would be to declare a property alias to your data model wherever it is defined, for example in your ListView QML file. This would make your data model accessible to the top level component in QML from this property alias. In effect, it gives you a global reference to your data model from anywhere else in QML.
For example, if you data model is called msg_DataSource, then in the QML file where it is defined you can create the property alias like this:
property alias myDataModel: msg_DataSource
Then in your ListItemComponent deleteMessage function, you can use myDataModel like this:
myDataModel.source = "newurl.com"
myDataModel.load();
Note: I am sure you could also do this in a more elegant way using signals and slots, but this way should be quicker and easier to understand.