How to use ArcItem with big stroke - qt

I'm using Qt Design Studio to define a ArcItem for a Gauge. The ArcItem needs a big Stroke Width to fill correct some background images later. The ArcItem is animated with the Timeline-Module, but when begin and end is same then I have this behavior shown in the image.
I tried then to change the Stroke Width through the Timeline by changing the Stroke Width to -1, if Begin (-125) and End (-125) are equal, but if I'm selecting frame 1, then the ArcItem is out of position.
This is frame 2
Question
How I can solve this issue and keep the Stroke Width?
Code
import QtQuick 2.12
import maskpietest 1.0
import QtQuick.Studio.Components 1.0
import QtQuick.Studio.Effects 1.0
import QtQuick.Controls 2.15
import QtQuick.Shapes 1.0
import QtQuick.Timeline 1.0
Rectangle {
id: rectangle
width: Constants.width
height: Constants.height
color: "#00000000"
layer.enabled: true
Slider {
id: slider
x: 0
y: 0
width: 791
height: 40
from: 0
to: 280
stepSize: 1
}
Label{
id: label
text: slider.value
x:8
y: 46
font.pointSize: 24
}
Rectangle {
width: 560
height: 560
color: "#00000000"
ArcItem {
id: arc
x: 274
y: 73
width: 520
height: 520
anchors.centerIn: parent
outlineArc: false
begin: -125
fillColor: "#00000000"
capStyle: 0
end: -125
strokeWidth: 100
strokeColor: "#37c1ff"
antialiasing: true
}
}
Timeline {
id: timeline
currentFrame: slider.value
animations: [
TimelineAnimation {
id: timelineAnimation
running: false
duration: 280
loops: 1
to: 280
from: 0
}
]
endFrame: 280
enabled: true
startFrame: 0
KeyframeGroup {
target: arc
property: "end"
Keyframe {
frame: 280
value: 125
}
}
KeyframeGroup {
target: arc
property: "strokeWidth"
Keyframe {
frame: 0
value: -1
}
Keyframe {
frame: 1
value: 100
}
}
}
}

Instead of changing the ArcItem strokeWidth you could just make it invisible on frame 0 and visible at frame 1:
KeyframeGroup {
target: arc
property: "visible"
Keyframe {
frame: 0
value: false
}
Keyframe {
frame: 1
value: true
}
}
Another solution (and probably the better one) is to set a specific Keyframe for the end property for frame 0:
KeyframeGroup {
target: arc
property: "end"
Keyframe {
frame: 0
value: -125
}
Keyframe {
frame: 280
value: 125
}
}

Related

connecting two (.ui.qml files) in Qt design studio

here Window_1 is the first screen, in this image home_1_1 is a component and i want to connect the Window_2 by clicking that component
import QtQuick 2.15
Rectangle {
id: window_1
width: 409
height: 560
color: "#ffffff"
Rectangle {
id: rectangle_1
x: 0
y: 0
width: 409
height: 560
color: "#d9d9d9"
}
Image {
id: home_1_1_2
x: 0
y: 0
source: "assets/home_1_1_2.png"
}
Image {
id: home_1_1
x: 179
y: 10
source: "assets/home_1_1.png"
Connections {
target: home_1_1
onClicked: window_1.state = "Window.2.ui.qml"
}
}
}
here Window_2 is normal window it will just appear and i imported Window_1.ui.qml
import QtQuick 2.15
import "Window_1.ui.qml"
Rectangle {
id: window_2
width: 409
height: 560
color: "#ffffff"
property alias temperatureText: temperature.text
property alias climateText: climate.text
Image {
id: home_1_1_1
x: 0
y: 0
source: "assets/home_1_1_1.png"
}
Image {
id: multilingual_1_1
x: 9
y: 309
source: "assets/multilingual_1_1.png"
}
Image {
id: down_1_1
x: 179
y: 0
source: "assets/down_1_1.png"
}
Image {
id: slice_1
x: 9
y: 214
source: "assets/slice_1.png"
}
Image {
id: clloud_sunny_2_1
x: 9
y: 226
source: "assets/clloud_sunny_2_1.png"
}
Text {
id: climate
x: 74
y: 222
width: 301
height: 58
color: "#ffffff"
text: qsTr("Climate ")
font.pixelSize: 36
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignTop
wrapMode: Text.Wrap
font.family: "Inter"
font.weight: Font.Normal
}
Text {
id: temperature
x: 74
y: 309
width: 301
height: 53
color: "#ffffff"
text: qsTr("Temperature")
font.pixelSize: 36
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignTop
wrapMode: Text.Wrap
font.family: "Inter"
font.weight: Font.Normal
}
}

QML: How to scale rotated Item around mouse point

I need scale and rotate a Rectangle around mouse point. When the Rectangle is not rotated my solution works fine, but if I apply Rotation transform I face the problem - my Rectangle move to an unexpected point. In my solution I use a MouseArea for drag the Rectangle, Scale and Rotation transforms for scale and rotate.
import QtQuick 2.0
Rectangle {
id: root
color: "gray"
Rectangle {
color: "black"
width: 360
height: 200
opacity: 0.5
x: 500
y: 350
}
Rectangle {
id: sample
color: "green"
width: 360
height: 200
opacity: 0.5
x: 500
y: 350
property real currX: 0
property real currY: 0
property real currZoom: 1
property real maxZoom: 5
property real minZoom: 0.5
transform: [
Scale {
id: scaler
origin.x: sample.currX
origin.y: sample.currY
xScale: sample.currZoom
yScale: sample.currZoom
},
Rotation{
id: rotation
origin.x: 180
origin.y: 100
angle: 30
}
]
MouseArea{
id: mouseArea
anchors.fill: parent
drag.target: sample
onClicked: mouse => {
zoom(true, mouse.x, mouse.y)
}
onWheel: (wheel) => {
var isIn = wheel.angleDelta.y > 0
zoom(isIn, wheel.x, wheel.y)
}
function zoom(isIn, x, y) {
var prevZoom = sample.currZoom
var prevX = sample.currX
var prevY = sample.currY
sample.currX = x
sample.currY = y
sample.currZoom = calculateZoom(isIn, prevZoom)
sample.x = sample.x + (prevX - sample.currX) * (1 - prevZoom)
sample.y = sample.y + (prevY - sample.currY) * (1 - prevZoom)
printSamplePostion()
}
function calculateZoom(isIn, prevZoom) {
var newZoom = isIn ? prevZoom + 0.1 : prevZoom - 0.1
if (newZoom > mouseArea.maxZoom)
newZoom = mouseArea.maxZoom
if (newZoom < mouseArea.minZoom)
newZoom = mouseArea.minZoom
return newZoom
}
function printSamplePostion() {
console.log("== x: 500 y: 350 ======")
console.log("-- x: " + sample.x)
console.log("-- y: " + sample.y)
console.log("=======================")
}
}
}
}
Thanks in advance

qml use same rectangle component for multiple objects

I am trying to reduce the size of qml file by calling same rectangle component and changing only the required fields and keep the rest same.
The part shown below is working but want to reduce the size.
Basically, I dont want to make moisture rectangle. I want to use temperature rectangle and modify say "x " value and inside connections modify only "path". Is that possible if yes than how ? thank you !!!
Rectangle {
id: landingScreen
x: 0
y: 0
width: 800
height: 350
color: "#E4E4E4"
visible: true
property string path: ""
property string val: ""
Rectangle {
id: temperature
x: 8
y: 11
width: 351
height: 329
color: "#ffffff"
radius: 10
Text{
id: textFieldtemp
text :qsTr("")
y:50
font.family: "Helvetica"
font.pointSize: 24
anchors.horizontalCenter: parent.horizontalCenter
}
Connections
{
target: myModel
onSensorValueChanged:{
path = "/root/temp"
val = value
if (addr === path)
{
textFieldtemp.text = "Temperature " + val + "*C"
}
}
}
}
Rectangle {
id: moisture
x: 369
y: 13
width: 209
height: 157
color: "#ffffff"
radius: 10
Text{
id: textFieldmoist
text :qsTr("")
y:50
font.family: "Helvetica"
font.pointSize: 24
anchors.horizontalCenter: parent.horizontalCenter
}
Connections
{
target: myModel
onSensorValueChanged:{
path = "/root/moist"
val = value
if (addr === path)
{
textFieldmoist.text = "Moisture " + val + "*C"
}
}
}
}
}
This sounds like you should just create a new QML file and give it some properties which you can set from the landingScreen. I named it SensorRectangle.qml
Rectangle {
id: sensor
color: "#ffffff"
radius: 10
property string address
property string title
property string unit
Text{
id: textField
property var value
text: sensor.title + " " + value + " " + sensor.unit
y:50
font.family: "Helvetica"
font.pointSize: 24
anchors.horizontalCenter: parent.horizontalCenter
}
Connections
{
target: myModel
onSensorValueChanged:{
if (addr === sensor.address)
{
textField.value = value
}
}
}
}
And then your landing screen becomes:
Rectangle {
id: landingScreen
x: 0
y: 0
width: 800
height: 350
color: "#E4E4E4"
visible: true
property string path: ""
property string val: ""
SensorRectangle {
id: temperature
x: 8
y: 11
width: 351
height: 329
title: "Temperature"
unit: "°C"
address: "/root/temp"
}
SensorRectangle {
id: moisture
x: 369
y: 13
width: 209
height: 157
title: "Moisture"
unit: "°C"
address: "/root/moist"
}
}

QML-How to change color of one point in chartview?

How to change color of one particular point in chartview in qml.i.e now all x axis values are displaying in black color but i want odd number to be displayed in red color.I want as shown in image where label colors in y axis are of different colors.
here is my piece of code
ChartView {
id:chartView
width: 2*horizontalList.width
height:horizontalList.height
antialiasing: true
animationOptions: ChartView.SeriesAnimations
legend.visible:false
ValueAxis {
id: scaleAxisX
min: 0
max: pointsX.length
tickCount: pointsX.length+1
labelFormat: "%.0f"
titleVisible: false
gridVisible: true
}
ValueAxis {
id: scaleAxisY
min: 0
max: 1.0
tickCount: 6
//labelFormat: "%.0f"
titleVisible: false
gridVisible: false
labelsVisible: false
labelsColor: "#757575"
}
ScatterSeries {
id: scatterSeries
axisXTop: scaleAxisX
axisY: scaleAxisY
color: "black"
markerSize: 12
}
}
As shown in second image ,the top line with red circle is a X axis(valueAxis) of chartview.i want to make the number inside the red circle to be in red color.
You can add a different ScatterSeries with color value;
import QtQuick 2.0
import QtCharts 2.0
ChartView {
title: "Scatters"
anchors.fill: parent
antialiasing: true
ScatterSeries {
color: "black"
id: scatter1
name: "Scatter1"
XYPoint { x: 1; y: 1 }
XYPoint { x: 2; y: 2 }
XYPoint { x: 3; y: 3 }
XYPoint { x: 4; y: 4 }
}
ScatterSeries {
color: "red"
name: "Scatter2"
XYPoint { x: 1.5; y: 1.5 }
}
}

Offset rotation for QML Item

In a QML application I have an item that is moving around the screen (not rotating). I want to display an indicator that rotates around this item, pointing away from the center of the screen, a fixed distance away from the center of the item.
The following simplified QML application performs this goal, by making the indicator a child of the item, and translating it to the desired location. However, when I try to rotate the indicator (the commented-out code) I cannot find any values for origin.x and .y that work. It feels like the QML scene graph calculates X/Y positioning in a way unlike any I've experienced.
import QtQuick 2.7
import QtQuick.Window 2.2
Window {
id: win
visible:true; width:600; height:300
property real padding: 50
property real angle: 0
property real _rads: angle * Math.PI/180
Timer {
interval:50; running:true; repeat:true
onTriggered:win.angle = (new Date/50) % 360
}
Rectangle {
id:object; color:'blue'
width:50; height:width
property real xOffset: Math.cos(_rads)
property real yOffset: Math.sin(_rads)
x: win.width/2 + xOffset * (win.width/2 - padding*2)
y: win.height/2 + yOffset * (win.height/2 - padding*2)
Rectangle {
id:indicator; color:'red'
property real centerOffset: 40
width:10; height:width*2
x: object.width/2 + object.xOffset * centerOffset - width/2
y: object.height/2 + object.yOffset * centerOffset - height/2
// transform: Rotation { origin.x:0; origin.y:0; angle:win.angle }
}
}
}
I've tried making the indicator not be a child of the item. I've tried using Translate in the transform stack instead of X/Y positions. All of them result in amusing-but-incorrect rotations.
How can I simply rotate the indicator around its own center, or otherwise achieve my goal?
You might think of it as a clock and build yourself a clockhand.
import QtQuick 2.7
import QtQuick.Window 2.2
Window {
id: win
visible:true; width:600; height:300
property real padding: 50
property real angle: 0
property real _rads: angle * Math.PI/180
Timer {
interval:50; running:true; repeat:true
onTriggered:win.angle = (new Date/50) % 360
}
Rectangle {
id:object; color:'blue'
width:50; height:width
property real xOffset: Math.cos(_rads)
property real yOffset: Math.sin(_rads)
x: win.width/2 + xOffset * (win.width/2 - padding*2)
y: win.height/2 + yOffset * (win.height/2 - padding*2)
Text {
width: 250
height: 250
x: -100
y: -100
text: '▲'
color: 'red'
font.pixelSize: 20
horizontalAlignment: Qt.AlignHCenter
verticalAlignment: Qt.AlignTop
transform: Rotation {
angle: win.angle + 90
origin.x: 125
origin.y: 125
}
}
Text {
x: 15
y: -125
width: 20
height: 20
text: '▲'
color: 'red'
font.pixelSize: 20
horizontalAlignment: Qt.AlignHCenter
verticalAlignment: Qt.AlignVCenter
transform: Rotation {
angle: win.angle + 90
origin.x: 10
origin.y: 150
}
}
Rectangle {
id: clockhand
width: 1
height: 100
color: 'black'
anchors {
centerIn: parent
}
rotation: win.angle + 90
Text {
text: '▲'
color: 'red'
anchors {
horizontalCenter: parent.horizontalCenter
bottom: parent.top
bottomMargin: -5
}
font.pixelSize: 20
}
}
}
}
Just turn the Clockhand into an Item and remove the color, to make it invisible.
Similar to #derM I have a solution that makes use of Item.rotation. However, with regard to the rest, I have generalized it by avoiding cos and sin since they are not required.
To demonstrate I create 3 SVG images crosshairs.svg, marker.svg, and triangle.svg. I placed crosshairs.svg in the center of the screen. I animate marker.svg by making it bounce around the screen "pong" style. Now, the secret sauce is the placement and orientation of triangle.svg.
To place an offset a triangle relative to the marker. I put the triangle Image inside an Item component. The Item component has no area, it merely has x, y, and rotation set. The Image component is placed relative to the Item and we need to compute its relative placement.
Because the triangle.svg is 16x16, I placed it at (20, -8) relative to the marker. If I had chosen (-8, -8) the SVG would sit on top of the marker. Because I put it at (20, -8) it puts it beyond the marker. Lastly, I compute the rotation using Math.atan2() on the vector between the marker and the crosshairs:
Item {
x: marker.x
y: marker.y
rotation: Math.atan2(
marker.y - crosshairs.y,
marker.x - crosshairs.x
) * 180 / Math.PI
Image {
source: "triangle.svg"
x: 20
y: -8
//cache: false
}
}
Here's a full working demo:
import QtQuick 2.15
import QtQuick.Controls 2.15
Page {
Timer {
interval: 50
running: true
repeat: true
onTriggered: marker.animate()
}
Rectangle {
id: frame
anchors.centerIn: parent
width: parent.width / 2
height: parent.height / 2
color: "#ffe"
border.color: "grey"
clip: true
Image {
id: crosshairs
anchors.centerIn: parent
source: "crosshair.svg"
//cache: false
}
Item {
id: marker
x: parent.width/2
y: parent.height/2
property int dx: 2
property int dy: 2
property int size: 20
Image {
anchors.centerIn: parent
source: "marker.svg"
//cache: false
}
function animate() {
x += dx;
y += dy;
if (x + size / 2 >= parent.width || x - size / 2 <= 0) {
dx = -dx;
x += dx;
x += dx;
}
if (y + size / 2 >= parent.height || y - size / 2 <= 0) {
dy = -dy;
py += dy;
py += dy;
}
}
}
Item {
x: marker.x
y: marker.y
rotation: Math.atan2(
marker.y - crosshairs.y,
marker.x - crosshairs.x
) * 180 / Math.PI
Image {
source: "triangle.svg"
x: 20
y: -8
//cache: false
}
}
}
}
//crosshair.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12"><path stroke="grey" d="M6 0L6 12M 0 6L 12 6"/></svg>
//marker.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path stroke="grey" fill="#ffe" d="M0 0 L20 0 L20 20 L0 20 z"/></svg>
//triangle.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path stroke="grey" fill="red" d="M16 8 L0 0 L 0 16z"/></svg>
You can Try it Online!

Resources