Paint a Path curve in QML with a shadow box - c++

I need to create a line like the image below. Does anyone have any suggestions?
target image
In addition to the mentioned image, it is necessary to select the line with the mouse, which can be done with TapHandler.

You can consider creating it with PathSvg.
import QtQuick
import QtQuick.Controls
import QtQuick.Shapes
Page {
background: Rectangle { color: "black" }
Frame {
anchors.centerIn: parent
padding: 0
width: 162
height: 80
background: Rectangle { color: "#444" }
Shape {
ShapePath {
strokeColor: "white"
PathSvg {
path: "M 0 20 L 155 59
155 57.5 162 60 155 62.5 155 61 0 22 z"
}
}
}
}
}
You can Try it Online!
Or you can consider implementing it as SVG:
import QtQuick
import QtQuick.Controls
Page {
background: Rectangle { color: "black" }
Frame {
anchors.centerIn: parent
padding: 0
background: Rectangle { color: "#222" }
Image {
source: "sample.svg"
sourceSize: Qt.size(width, height)
width: 128
height: 80
}
}
}
// sample.svg
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 20">
<path stroke="white" stroke-width="0.4" fill="white" d="M 0 4 L 31 11.8
31 11.5 32 12 31 12.5 31 12.2 0 4.4 z"/>
</svg>
You can Try it Online!

Related

ListView with List Items arranged on Half Circle using QML

I'm Trying to make a Circular ListView with List Items arranged on Half Circle. it should look something like this:
I'm using Qt open source license and i cannot find a controller similar in QtControls.
Please any idea or suggestion ?
Thanks in advance
Here is a solution based on the link that folibis shared in the comments above using PathView to layout the items of a model along a PathArc.
import QtQuick
import QtQuick.Window
import QtQuick.Shapes
Window {
visible: true
width: 400
height: 400
Shape {
ShapePath {
strokeWidth: 2
strokeColor: "black"
fillColor: "lightgrey"
startX: 0
startY: 0
PathArc {
x: 0
y: 400
radiusX: 400
radiusY: 400
}
}
}
Shape {
x: 100
ShapePath {
strokeWidth: 2
strokeColor: "grey"
startX: 0
startY: 0
PathArc {
x: 0
y: 400
radiusX: 400
radiusY: 400
}
}
}
PathView {
x: 100
model: ["Apple", "Banana", "Cherry", "Dragonfruit", "Grapefruit", "Orange", "Papaya"]
delegate: Item {
width: 50
height: 50
Rectangle {
height: 50
width: 260
radius: 25
color: "lightgrey"
}
Rectangle {
id: circle
width: 50
height: 50
radius: 25
color: "darkgrey"
}
Text {
anchors.leftMargin: 10
anchors.left: circle.right
anchors.verticalCenter: parent.verticalCenter
text: modelData
font.pixelSize: 24
}
}
path: Path {
// Those 2 coordinates are a bit of hack to push down the first item on the actual arc
// so it won't stick out the top. There might be a better way of doing that
startX: 18
startY: 35
PathArc {
x: 0
y: 400
radiusX: 400
radiusY: 400
}
}
}
}

How to trigger an animation qml when a value from C++ change?

I have an application which use C++ and QML.
In my C++ : I read the value and i send it to QML in order to show it in a slider.
My value change when i press in my hardware.
My problem is in the QML part:
In QML :
I need to trigger an animation for few seconds when this value change. I only need to show this animation when the value from c++ part Change.
if someone could help ?
I already tried the QML timer but not showing animation when value changed ?
Some code in QML part for the animation :
VolumeRemote.QML
Rectangle {
id: item1
width: 550
height: 110
color: "#0a0a07"
border.color: "#ffffff"
opacity: 1
SliderComponent{
id:slider
x: 34
y: 79
width: 466
height: 5
minimumValue: 0
//here i give the value from C++ to my slider
//Controller is a global Qobject where i define some stuff
value: Controller.volume_radio
onValueChanged: {
animation.running=true;
}
PropertyAnimation {
id:myanimation
running: true
target:item1
property: 'visible'
to: false
duration: 10000
}
}
Text {
id: text1
x: 93
y: 16
width: 170
height: 41
color: "#ffffff"
text: qsTr("Radio Volume :")
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
font.pixelSize: 24
font.family: regular.name
}
Text {
id: valeurslider
x: 277
y: 16
// x: 618
//y: 45
width: 24
height: 41
color: "#ffffff"
text: slider.value
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
opacity: 0.45
font.pixelSize: 30
font.family: regular.name
}
Image {
id: image1
x: 34
y: 16
width: 44
height: 41
source: "assets/ic_sound_popup_on.png"
}
}
You have two options
A local property and its change signal
readonly property qreal valueFromCpp: Controller.volume_radio
onValueFromCppChanged: // trigger animation
A Connections element
Connections {
target: Controller
onNameOfThePropertyNotifySignal: // trigger animation
}
if you use this in the C++ part: Q_PROPERTY(int RadioVolume READ getval NOTIFY val_signal ), you have to add a write function to change RadioVolume. Tha is to say:
Q_PROPERTY(int RadioVolume READ getval WRITE setVal NOTIFY val_signal ) and in the function setVal(), you have to change the RadioValume variable value and you have to emit the val_signal everytime the value changes. Instead of setting the value directly, call the setVal() function everywehre you set RadioVolume value and then in the QML part you have to put this: onVal_Signal: put the animation here
If you have any question regarding my answer do not hesitate to ask. If you have the code, i will be glad to help you change it
I use #Beloqui and #KevinKrammar second answer :
1 - Declare simple animation with property visible
2 - SliderCompenent and give the value : Controller.volume_radio
3 - use of connections in order to get the signal notified from C++ : OnVolumesignal
Then i can trigger the animation when signal is emitted from c++ part
Here a small piece of code :
import QtQuick 2.0
import QtQuick 2.0
import Controllers 1.0
import "Logic.js" as Controller_Js
Rectangle {
id: item1
width: 550
height: 110
color: "#0a0a07"
border.color: "#ffffff"
opacity: 1
visible: Controller.stateVol
SliderComponent{
id:slider
x: 34
y: 79
width: 466
height: 5
minimumValue: 0
maximumValue: 100
value: Controller.volume_radio
NumberAnimation {
id: animation
target: item1
property: "visible"
duration: 1000
easing.type: Easing.InOutQuad
}
//gestion du signal
Connections{
target:commodo
onVolumesignal:{
if (commodo.RadioVolume !==100){
Controller.stateVol=true
animation.start();
console.log("state of controller :", Controller.stateVol)
} else if (commodo.RadioVolume>100){
animation.stop();
Controller.stateVol=false
console.log("state", Controller.stateVol)
}
}
}
Cobntroller.stateVol is defined to false in my controller.qml
Thanks guys, it really helped me.

Generating .cpp and.h file from ..qml file in qt creator

How to generate a .cpp and .h file for login.qml file?
I have written a .qml file for a login page.
my code is as following
import QtQuick 1.0
Rectangle{
id:screen
color: "lightgray"
width: 3000; height:2700
Column {
id: column1
width: 201
height: 400
Row {
id: row1
width: 40
height:50
TextInput {
id: userName
x: 40
y: 18
width: 80
height: 20
text: qsTr("UserName")
font.pixelSize: 12
}
Rectangle {
id: rectangle1
x: 115
y: 18
width: 80
height: 20
color: "#ffffff"
}
}
Row {
id: row2
width: 40
height: 50
TextInput {
id: password
x: 40
y: 18
width: 80
height: 20
text: qsTr("Password")
font.pixelSize: 12
}
Rectangle {
id: rectangle2
x: 115
y: 18
width: 80
height: 20
color: "#ffffff"
}
}
Row {
id: row3
x: 8
y: 113
width: 40
height: 50
Rectangle {
id: rectangle3
x: 8
y: 8
width: 80
height: 20
color: "#ffffff"
Text {
id: login
text: "Login"
x:4
y:4
width:30
height:10
font.pixelSize: 12
}
}
}
}
MouseArea {
anchors.fill: parent
onClicked: {
myclass.doStuffFromQmlSlot();
Qt.quit();
}
}
}
That would be quite some work.
You would need to write a C++ code generator or find an existing one.
You would either need to parse the QML code or load it and traverse the tree to feed your code generator.
Your generated code would then either depend on private Qt headers or you need your own implementations for the QtQuick types.

qml and c++ with qt quick 2 application

I have a qml GUI of my main window. I just created a qt quick2 application and copied and pasted qml GUI of my main window to main.qml. When I run the application, it displays blank window and following is my qml log:
QML debugging is enabled. Only use this in a safe environment.
Both point size and pixel size set. Using pixel size.
Both point size and pixel size set. Using pixel size.
Both point size and pixel size set. Using pixel size.
file:///home/khajvah/build-convQML-Desktop_Qt_5_1_0_GCC_64bit-Debug/qml/convQML/main.qml:99:9: QML Text: Cannot anchor to an item that isn't a parent or sibling.
file:///home/khajvah/build-convQML-Desktop_Qt_5_1_0_GCC_64bit-Debug/qml/convQML/main.qml:31:9: QML BasicButton: Cannot anchor to an item that isn't a parent or sibling.
file:///home/khajvah/Qt5.1.0/5.1.0/gcc_64/qml/QtQuick/Controls/Styles/Base/ToolButtonStyle.qml:73:9: QML Image: Cannot open: file:///home/khajvah/build-convQML-Desktop_Qt_5_1_0_GCC_64bit-Debug/logout-512.png
file:///home/khajvah/Qt5.1.0/5.1.0/gcc_64/qml/QtQuick/Controls/Styles/Base/ToolButtonStyle.qml:73:9: QML Image: Cannot open: file:///home/khajvah/build-convQML-Desktop_Qt_5_1_0_GCC_64bit-Debug/console.ico
file:///home/khajvah/Qt5.1.0/5.1.0/gcc_64/qml/QtQuick/Controls/Styles/Base/ToolButtonStyle.qml:73:9: QML Image: Cannot open: file:///home/khajvah/build-convQML-Desktop_Qt_5_1_0_GCC_64bit-Debug/mod.png
QQuickView only supports loading of root objects that derive from QQuickItem.
If your example is using QML 2, (such as qmlscene) and the .qml file you
loaded has 'import QtQuick 1.0' or 'import Qt 4.7', this error will occur.
To load files with 'import QtQuick 1.0' or 'import Qt 4.7', use the
QDeclarativeView class in the Qt Quick 1 module.
the following is my qml file:
import QtQuick 2.1
import QtQuick.Controls 1.0
import QtQuick.Window 2.0
ApplicationWindow {
id: applicationwindow1
title: qsTr("Converter")
width: 500
//height: 600
// menuBar: MenuBar {
// }
ToolBar {
id: tool_bars
x: 0
y: 0
width: applicationwindow1.width
height: 39
clip: true
smooth: false
opacity: 1
transformOrigin: Item.Center
ToolButton {
id: modify
y: 1
scale: 1
anchors.right: tool_bars.left
iconSource: "../../mod.png"
}
ToolButton {
id: consolebtn
x: 32
y: 1
scale: 1
anchors.left: modify.right
anchors.leftMargin: 6
iconSource: "../../console.ico"
}
ToolButton {
id: exit;
x: 75
y: 1
scale: 1
anchors.left: consolebtn.right;
anchors.leftMargin: 6
iconSource: "../../logout-512.png"
}
}
GroupBox {
id: group_box1
x: 0
y: 30
width: 500
height: 136
anchors.top: tool_bars.bottom
anchors.topMargin: -9
anchors.left: parent.left
anchors.leftMargin: 0
anchors.right: parent.right
anchors.rightMargin: 0
ComboBox {
id: typebox
anchors.left: text1.right
anchors.leftMargin: 5
width: 70
height: 23
anchors.top: parent.top
anchors.topMargin: 37
}
Text {
id: text1
anchors.left: group_box1.left
anchors.leftMargin: 5
text: "Type:"
anchors.top: parent.top
anchors.topMargin: 41
font.italic: true
style: Text.Normal
font.pointSize: 12
font.pixelSize: 12
}
ComboBox {
id: frombox
x: 205
anchors.left: text2.right
anchors.leftMargin: 8
width: 70
height: 23
anchors.top: parent.top
anchors.topMargin: 37
}
Text {
id: text2
x: 189
anchors.leftMargin: 20
text: "From:"
anchors.top: parent.top
anchors.topMargin: 41
anchors.horizontalCenterOffset: -32
anchors.horizontalCenter: parent.horizontalCenter
font.italic: true
style: Text.Normal
font.pointSize: 12
font.pixelSize: 12
}
ComboBox {
id: tobox
x: 412
anchors.right: parent.right
anchors.rightMargin: 5
width: 70
height: 23
anchors.top: parent.top
anchors.topMargin: 37
}
Text {
id: text3
x: 0
text: "To:"
anchors.top: parent.top
anchors.topMargin: 41
anchors.right: tobox.left
anchors.rightMargin: 5
font.italic: true
style: Text.Normal
font.pointSize: 12
font.pixelSize: 12
}
TextField {
id: text_field1
y: 78
width: 197
height: 22
anchors.bottom: parent.bottom
anchors.bottomMargin: 15
anchors.left: parent.left
anchors.leftMargin: 5
placeholderText: "Input"
}
TextField {
id: text_field2
x: 293
y: 78
width: 186
height: 22
anchors.bottom: parent.bottom
anchors.bottomMargin: 15
anchors.right: parent.right
anchors.rightMargin: 5
readOnly: true
placeholderText: "Result"
}
}
TextArea {
id: text_area1
x: 0
y: 178
width: 500
height: 80
anchors.left: parent.left
anchors.leftMargin: 0
anchors.right: parent.right
anchors.rightMargin: 0
anchors.top: group_box1.bottom
anchors.topMargin: 12
anchors.bottom: addlogbtn.top
anchors.bottomMargin: 5
}
Button {
id: addlogbtn
x: 7
y: 212
width: 110
height: 23
text: "Add to Log"
anchors.bottom: parent.bottom
anchors.bottomMargin: 5
anchors.left: parent.left
anchors.leftMargin: 7
}
Button {
id: button1
x: 195
y: 212
width: 118
height: 23
text: "Export"
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: 5
}
Button {
id: button2
x: 359
y: 212
width: 117
height: 23
text: "Clear"
anchors.right: parent.right
anchors.rightMargin: 7
anchors.bottom: parent.bottom
anchors.bottomMargin: 5
}
}
and automatically generated main.cpp:
#include <QtGui/QGuiApplication>
#include "qtquick2applicationviewer.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QtQuick2ApplicationViewer viewer;
viewer.setMainQmlFile(QStringLiteral("qml/convQML/main.qml"));
viewer.showExpanded();
return app.exec();
}
Any ideas why this does not work? I am new to qml and I am really confused how it is connected to c++.
You can definitely use ApplicationWindow, but you need to use QQmlApplicationEngine, and you need to explicitly show your toplevel window. You can see a complete example in another answer. Below is just a main.cpp file that should work for you.
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickWindow>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl("qml/convQML/main.qml"));
QObject *topLevel = engine.rootObjects().value(0);
QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);
window->show();
return app.exec();
}

QML listview reading current and touch area

I have this problem. I have listview which I populate from QT code , but I want to listview to be touchable, so when I click I can actually select certain item. Now I can navigate with arrows up and down, but when I port it to Android it doesn't work. I have tried to add mouse area, but I can't make it work with listview. So that's problem no.1 and second question is about getting selected item. So when I click on certain item in list I want to read data from it.
Here is a piece of my code if you need more just let me know:
ListView {
id: listview1
x: 0
y: 82
width: 395
height: 942
visible: true
keyNavigationWraps: false
boundsBehavior: Flickable.DragAndOvershootBounds
opacity: 1
maximumFlickVelocity: 2500
anchors.leftMargin: 0
highlightMoveSpeed: 489
contentWidth: 0
preferredHighlightEnd: 2
spacing: 5
highlightRangeMode: ListView.NoHighlightRange
snapMode: ListView.SnapToItem
anchors.bottomMargin: 0
anchors.rightMargin: 179
anchors.topMargin: 82
anchors.fill: parent
model: myModel
delegate:Component {
// id: contactDelegate
Item {
property variant myData: model
width: 450; height: 90
Column {
Text { text: '<b>ID: </b> ' + id_korisnika ; color:"steelblue"; font.family: "Helvetica"; font.pointSize: 8 }
Text { text: '<b>Ime: </b> ' + ime_korisnika ; color:"steelblue"; font.family: "Helvetica"; font.pointSize: 8 }
Text { text: '<b>Prezime: </b> ' + prezime_korisnika; color:"steelblue"; font.family: "Helvetica"; font.pointSize: 8 }
Text { text: '<b>Broj telefona: </b> ' + broj_korisnika ; color:"steelblue"; font.family: "Helvetica"; font.pointSize: 8 }
Text { text: '<b>Adresa: </b> ' + adresa_korisnika ; color:"steelblue"; font.family: "Helvetica"; font.pointSize: 8 }
}
}
}
// delegate: contactDelegate
highlight: Rectangle {color:"black"; radius: 5; opacity: 0.7 }
focus: true
}
BorderImage {
id: border_image1
x: 0
y: 0
width: 501
height: 81
source: "slike/naslov.png"
MouseArea {
id: mouse_area1
x: 0
y: 81
anchors.fill: parent
}
}
Rectangle {
id: rectangle1
x: 395
y: 82
width: 100
height: 718
gradient: Gradient {
GradientStop {
position: 0
color: "#f3eeee"
}
GradientStop {
position: 1
color: "#621717"
}
}
Image {
id: image1
x: 2
y: 314
width: 100
height: 100
source: "slike/Button-Next-icon.png"
}
}
//dodaj korisnika
Flipable {
id: flipable
x: 401
y: 98
width: 87
height: 70
property bool flipped: false
front: Image { x: 0; y: 0; width: 60; height: 58; source: "slike/dodaj_korisnika.png"; anchors.centerIn: parent }
back: Image { x: 0; y: 0; width: 60; height: 58; source: "slike/accept.png"; anchors.centerIn: parent }
transform: Rotation {
id: rotation
origin.x: flipable.width/2
origin.y: flipable.height/2
axis.x: 1; axis.y: 0; axis.z: 0 // set axis.y to 1 to rotate around y-axis
angle: 0 // the default angle
}
states: State {
name: "back"
PropertyChanges { target: rotation; angle: 180 }
when: flipable.flipped
}
transitions: Transition {
NumberAnimation { target: rotation; property: "angle"; duration: 500 }
}
MouseArea {
x: 7
y: 9
width: 73
height: 76
anchors.rightMargin: 7
anchors.leftMargin: 7
anchors.topMargin: 9
anchors.bottomMargin: 9
hoverEnabled: false
anchors.fill: parent
onClicked: {
if(Varijabla.unos_korisnika==1)
{ window.state == 'State1' ? window.state = "" : window.state = 'State1'; flipable.flipped = !flipable.flipped; Varijabla.povecaj() }
else if(Varijabla.unos_korisnika==2)
{
window.state == "" ? window.state = 'State1' : window.state = ""; flipable.flipped = !flipable.flipped; Varijabla.reset();
funkcije.dodaj_korisnika(text_input1.text,text_input2.text,text_input3.text,text_input4.text);
}
}
}
These are text variables available:
TextInput {
id: text_input1
x: 59
y: 131
width: 80
height: 20
font.pixelSize: 12
opacity: 0
}
TextInput {
id: text_input3
x: 59
y: 246
width: 80
height: 20
font.pixelSize: 12
opacity: 0
}
TextInput {
id: text_input4
x: 59
y: 305
width: 80
height: 20
font.pixelSize: 12
opacity: 0
}
TextInput {
id: text_input2
x: 59
y: 190
width: 80
height: 20
font.pixelSize
: 12
opacity: 0
}
MouseArea inside delegate should work just fine, declare a signal in your ListView and emit it from delegate/MouseArea. You can emit arbitrary data, but in most cases model index is enough:
ListView {
signal itemSelected(int index)
delegate: Rectangle {
MouseArea {
anchors.fill: parent
onClicked: itemSelected(model.index)
}
}
}