How to set an item property of one qml from main.qml - qt

I waste my time to find how set the visible property to false, the delegate being in an another qml file.
For instance here is a simple example based on Places Map.
Marker.qml
import QtQuick 2.0
import QtLocation 5.6
MapQuickItem {
id: idPointsMarker
sourceItem: Loader{sourceComponent: idRect}
visible: true //if set manually to false, everything works correctly
Component{
id: idRect
Rectangle{
width: 20
height: 20
color: "blue"
}
}
}
and the main.qml
import QtQuick 2.0
import QtQuick.Window 2.0
import QtLocation 5.6
import QtPositioning 5.6
Window {
width: 512
height: 512
visible: true
PositionSource {
...
}
property variant locationOslo: QtPositioning.coordinate( 59.93, 10.76)
PlaceSearchModel {
...
}
Map {
id: map
anchors.fill: parent
plugin: Plugin {name: "osm"}
center: locationOslo
zoomLevel: 13
MouseArea {
id : mouseMap
anchors.fill: parent
onDoubleClicked: {
console.log("DoubleClicked")
Marker.idPointsMarker.visible = false // pb is here
}
}
MapItemView {
model: searchModel
delegate: Marker{
coordinate: place.location.coordinate
}
}
}
}
I wish to toggle the visibility to false on doubleclick. I am not able to access the property anyhow the way i write it. What is the correct syntax?
Sorry for a so simple question. Thanks for help.

You do not have to set the property in main.qml, you must do it in Marker.qml, since the elements of Marker.qml can access all the elements of main.qml. One solution is to establish a property of type bool that manages the visibility and that changes in the double click:
main.qml
Map {
[...]
property bool isVisibleItems: true
MouseArea {
id : mouseMap
anchors.fill: parent
onDoubleClicked: map.isVisibleItems = !map.isVisibleItems
}
[...]
Marker.qml
import QtQuick 2.0
import QtLocation 5.6
MapQuickItem {
id: idPointsMarker
sourceItem: Loader{sourceComponent: idRect}
visible: map.isVisibleItems
Component{
id: idRect
Rectangle{
width: 20
height: 20
color: "blue"
}
}
}
In the following link there is an example

Related

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 draw an element over following items in QML layouts

I'm working on a DatePicker control for QtQuick.Controls 2.0 I have problem on drawing popup calendar over other page items. does anyone help me on this ?
Component Screenshot
My DatePicker source code:
import QtQuick 2.0
import QtQuick.Controls 2.0
import QtQuick.Controls 1.4 as OldControls
Rectangle {
id: root
width: childrenRect.width
height: childrenRect.height
clip: true
property bool expanded: false
property bool enabled: true
property alias selectedDate: cal.selectedDate
MouseArea {
height: expanded ? txt.height + cal.height : txt.height
width: expanded ? Math.max(txt.width, cal.width) : txt.width
hoverEnabled: true
enabled: root.enabled
onHoveredChanged: {
expanded = root.enabled && containsMouse
}
TextField {
id: txt
enabled: root.enabled
text: cal.selectedDate
inputMask: "0000-00-00"
}
OldControls.Calendar {
id: cal
anchors.top: txt.bottom
anchors.left: txt.left
visible: expanded
}
}
}
and here is my DatePicker usage in page:
import QtQuick 2.0
import QtQuick.Layouts 1.0
import QtQuick.Controls 2.2
import "./Components"
Item {
anchors.fill: parent
GridLayout {
columns: 2
Text { text: qsTr("Date Filter: ") }
DatePicker {}
Text { text: qsTr("name filter: ") }
TextField {}
}
}

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.

Take snapshot of video in Qt Multimedia

Is it possible to take snapshot of a video in Qt Multimedia? how?
It depends on the platform but what you can probably do is to use a QMediaPlayer, set a subclassed video surface via setVideoOutput, and get the frame data from the QVideoFrame passed in the present method. You'll then have to deal with the frame format and to map if those are not in CPU memory.
However, depending on your need, I would use ffmpeg/libav to get a frame from a specific position.
Try this (Documentation here: http://doc.qt.io/qt-5/qml-qtquick-item.html#grabToImage-method)
import QtQuick 2.5
import QtQuick.Window 2.2
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.1
import QtMultimedia 5.0
Window {
id: mainWindow
visible: true
width: 480
height: 800
MediaPlayer {
id: player
source: "file:///location/of/some/video.mp4"
autoPlay: false
}
ColumnLayout {
anchors.fill: parent
VideoOutput {
id: output
source: player
Layout.fillHeight: true
Layout.fillWidth: true
}
Row {
id: buttonsRow
height: 100
spacing: 20
anchors.horizontalCenter: parent.horizontalCenter
Layout.margins: 10
Button {
id: playPauseButton
text: player.playbackState === MediaPlayer.PlayingState ? "Pause" : "Play"
onClicked: {
var playing = player.playbackState === MediaPlayer.PlayingState;
playing ? player.pause() : player.play();
}
}
Button {
text: "Snapshot"
onClicked: {
output.grabToImage(function(image) {
console.log("Called...", arguments)
image.saveToFile("screen.png"); // save happens here
});
}
}
}
}
}

Resources