How to pass double from Qt c++ code to QML code? - c++

I have this code in Qt
int main(int argc, char *argv[]) {
QGuiApplication app(argc,argv);
QQuickView view;
QUrl q(QStringLiteral("QML:///places_map.qml"));
view.setSource(QUrl(QStringLiteral("qrc:///places_map.qml")));
//I've tried this to init qml properties
QObject *object = view.rootObject();
object->setProperty("latitude", 48.4656371);
object->setProperty("longitude", 31.04900455);
QQuickItem *item = view.rootObject();
item->setProperty("device_latitude", 48.4656371);
item->setProperty("device_longitude", 35.04900455);
}
And my qml file:
import QtQuick 2.0
import QtPositioning 5.5
import QtLocation 5.6
Rectangle {
width: 720
height: 480
property double latitude: 0
property double longitude: 0
property double device_latitude: 0 //48.4656371
property double device_longitude: 0 //35.54900455
property variant location: QtPositioning.coordinate(latitude, longitude)
property variant deviceLocation: QtPositioning.coordinate(device_latitude, device_longitude)
Plugin {
id: myPlugin
name: "osm"
}
PlaceSearchModel {
id: searchModel
plugin: myPlugin
searchTerm: "Pizza"
searchArea: QtPositioning.circle(deviceLocation)
Component.onCompleted: update()
}
Map {
id: map
anchors.fill: parent
plugin: myPlugin;
center: location
zoomLevel: 13
MapItemView {
model: searchModel
delegate: MapQuickItem {
coordinate: deviceLocation //QtPositioning.coordinate(device_latitude, device_longitude)
anchorPoint.x: image.width * 0.5
anchorPoint.y: image.height
sourceItem: Column {
Image { id: image; source: "marker.png" }
Text { text: title; font.bold: true }
}
}
}
}
}
In qml code properties double latitude and longitude set the view on map
but map shows place with latitude = 0 and longtitude = 0
If I set the correct coordinates in qml code everything works
How can I init this value from c++ code so that map will show my city ?

Using Q_PROPERTY would be better. Exposing Attributes of C++
I have it working like this:
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickItem>
#include <QQuickView>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQuickView view;
view.setSource(QUrl(QStringLiteral("qrc:/main.qml")));
QQuickItem *item = view.rootObject();
item->setProperty("number", 22.002);
view.show();
return app.exec();
}
main.qml
import QtQuick 2.4
import QtQuick.Window 2.2
Rectangle{
visible: true
width: 640
height: 480
property double number : 0
Text {
id: textEdit
text: number
verticalAlignment: Text.AlignVCenter
anchors.top: parent.top
anchors.horizontalCenter: parent.horizontalCenter
anchors.topMargin: 20
}
}

Related

qml draw a Linechart from Qlist using a repeater

I want to draw a plot of sensor data that is saved in a QList. I know that getting the data up to the qml level works fine, because it correctly prints to console (see code).
My question now is, how can I draw a LineChart out of this data? I tried a repeater and some sketchy for- loops but none seem to work and only an empty chart is displayed.
As stated above, the data works and is logged correctly. The axis are correct as well, there just is no line.
My most promising try:
import QtQuick 2.0
import QtCharts 2.3
Item {
width:400
height:600
ChartView
{
width:parent.width
height:parent.height
Component.onCompleted: {
//Data displayed correctly
console.log(device.AIN3data.length);
console.log(device.AIN3data)
}
ValueAxis {
id: axisX
min: 0
max: device.AIN3data.length
}
ValueAxis {
id: axisY
min: 0
max: 1000
}
LineSeries
{
axisX: axisX
axisY:axisY
name: "AIN3"
Repeater
{
model: device.AIN3data.length
XYPoint{x:index;y:device.AIN3data[index]}
Component.onCompleted: console.log("Repeater")
}
}
}
}
Repeater is used to generate several Items, not for XYPoint. In this case it is better to create a C++ model, export it to QML and then map to a LineSeries using VXYModelMapper.
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QStandardItemModel>
#include <QTimer>
#include <random>
int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
QApplication app(argc, argv);
QStandardItemModel model(0, 2);
QTimer timer;
timer.setInterval(1000);
QObject::connect(&timer, &QTimer::timeout, &model, [&model](){
static std::default_random_engine e;
static std::uniform_real_distribution<> dis(0, 1000);
QStandardItem *xItem = new QStandardItem;
QStandardItem *yItem = new QStandardItem;
xItem->setData(model.rowCount(), Qt::DisplayRole);
yItem->setData(dis(e), Qt::DisplayRole);
model.appendRow({xItem, yItem});
});
timer.start();
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("dataModel", &model);
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
import QtCharts 2.3
import QtQuick 2.15
import QtQuick.Window 2.15
Window {
width: 640
height: 480
visible: true
title: qsTr("Hello World")
ChartView {
anchors.fill: parent
ValueAxis {
id: axisX
min: 0
max: lineSeries.count - 1
}
ValueAxis {
id: axisY
min: 0
max: 1000
}
LineSeries {
id: lineSeries
axisX: axisX
axisY: axisY
}
}
VXYModelMapper {
id: modelMapper
model: dataModel
series: lineSeries
xColumn: 0
yColumn: 1
}
}

why qml virtualkeyboard is not show after click on edit text ,while I call plugin in .pro and main.cpp

I use open source qt5.9 for an embedded device.
I wanna to use virtual keyboard in my qml project. I know I should add a static link in .pro file like :
static {
QT += svg
QTPLUGIN += qtvirtualkeyboardplugin
}
and also add
#include <QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
to main.cpp file to use the virtual keyboard. but my virtual keyboard does not fire when I click on my text object:
import QtQuick 2.9
import QtQuick.Window 2.2
import QtQuick.VirtualKeyboard 2.1
Window {
visible: true
width: 640
height: 480
TextInput {
id: textInput;
text:"ssssss"
height: 120;
width: parent.width - 2;
anchors.bottom: keyboard.top
color: "#000000"; // black
// http://doc.qt.io/qt-5/qinputmethod.html#properties
focus: Qt.inputMethod.visible;
verticalAlignment: TextInput.AlignVCenter;
}
}
It solved.
just put the kind of input for each lineedit . like this :
InputPanel{
id:inputpanel
visible:active
y:active?parent.height - inputpanel.height : parent.height
anchors.left: parent.left
anchors.right: parent.right
}
TextInput{
id:input
inputMethodHints: Qt.ImhDigitsOnly
focus: Qt.inputMethod.visible;
text: "123211"
}
TextInput{
id:input2
anchors.top:input.bottom
inputMethodHints: Qt.ImhLowercaseOnly
focus: Qt.inputMethod.visible;
text: "123211"
}

QML and C++ connect to signal

I want to connect QML Signals to c++ functions. I do not really understand how I can get the right item. Right now I try it in the following way, which is not working (Also, would there be easier ways?), here is the code I tried:
main.cpp:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "include/myclass.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
QQmlComponent component(&engine, "qrc:/Page1.qml");
QObject *item = component.create();
MyClass myClass;
QObject::connect(item, SIGNAL(testSignal()),&myClass,SLOT(cppSlot()));
return app.exec();
}
main.qml:
import QtQuick 2.7
import QtQuick.Controls 2.0
import QtQuick.Layouts 1.0
ApplicationWindow {
visible: true
width: 800
height: 460
Page1 {
id: page1
visible: true
}
}
Page1.qml:
import QtQuick 2.7
import QtQuick.Window 2.2
Item {
width: 800
height: 460
signal testSignal()
CustomButton {
id: cppSignalButton
x: 14
y: 55
buttonText: "Test CPP Signal"
onButtonClicked: {
testSignal();
}
}
}
CustomButton.qml:
import QtQuick 2.7
import QtQuick.Window 2.2
Rectangle {
id: root
width: 200
height: 50
color: "#000000"
border.color: "#FFFFFF"
property string buttonText
signal buttonClicked()
MouseArea {
id: mouseArea
anchors.fill: parent
onClicked:{
root.buttonClicked();
}
}
Text {
id: text1
x: 105
y: 31
color: "#ffffff"
text: buttonText
anchors.verticalCenter: parent.verticalCenter
anchors.horizontalCenter: parent.horizontalCenter
font.pixelSize: 20
}
}
and myclass.cpp:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <iostream>
#include <fstream>
#include <QQuickItem>
#include <QQuickView>
class MyClass : public QObject
{
Q_OBJECT
public:
MyClass(){
};
public slots:
void cppSlot() {
std::ofstream textfile;
textfile.open("test.txt");
textfile << "Signal worked" << std::endl;
textfile.close();
qInfo( "Called the C++ slot" );
}
};
First you should read this article: Integrating QML and C++
You can invoke your MyClass object method from qml in the following way:
//main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "include/myclass.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
MyClass myClass;
engine.rootContext()->setContextProperty("myClass", &myClass);
engine.load(QUrl(QLatin1String("qrc:/main.qml")));
return app.exec();
}
//Page1.qml
import QtQuick 2.7
import QtQuick.Window 2.2
Item {
width: 800
height: 460
signal testSignal()
CustomButton {
id: cppSignalButton
x: 14
y: 55
buttonText: "Test CPP Signal"
onButtonClicked: {
myClass.cppSlot(); //now you can use the context property to invoke your slot
}
}
}

QT 5.7 QML - Reference Error: Class is not defined

I get the "qrc:/main_left.qml:23: ReferenceError: CppClass is not defined" when I run the below code. This code tries to change the position of a rectangle in a window.
Main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "cppclass.h"
#include "bcontroller.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
//QGuiApplication app(argc, argv);
BController c;
CppClass cppClass;
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("CppClass", &cppClass);
engine.load(QUrl(QStringLiteral("qrc:/main_left.qml")));
return app.exec();
}
main_left.qml
import QtQuick 2.7
import QtQuick.Window 2.2
import QtQuick.Controls 1.2
Rectangle {
visible: true
width: 640
height: 480
property int index: 0
Text {
text: controller.name
anchors.centerIn: parent
}
Image{
id:imageLeft
anchors.fill: parent
source:"imageLeft.jpg";
}
Connections {
target: CppClass
onPosUpdate: {
rect.x = currentPos
}
}
Button {
id: button1
x: 163
y: 357
text: qsTr("Change Position")
anchors.bottom: parent.bottom
anchors.bottomMargin: 20
anchors.horizontalCenter: parent.horizontalCenter
onClicked: CppClass.getCurrentPos()
}
Rectangle {
id: rect
width: parent.width/2
height: parent.height/2
color: "transparent"
border.color: "red"
border.width: 5
radius: 10
}
MouseArea {
anchors.fill: parent
onClicked: controller.setName(++index)
}
}
cppclass.cpp
#include "cppclass.h"
#include <QtQuick>
#include <string>
CppClass::CppClass(QObject *parent) : QObject(parent)
{
}
CppClass::~CppClass()
{
}
void CppClass::getCurrentPos()
{
int pos = rand() % 400;
std::string s = std::to_string(pos);
QString qstr = QString::fromStdString(s);
emit posUpdate(qstr);
}
Please help!
I think there is a problem with CppClass declaration in your main.cpp => CppClass cppClass; and your CppClass constructor is CppClass::CppClass(QObejct *parent); which means that you are missing the constructor parameter.
Therefore,you have two possibilities
1st : Try use your class without QObject *parent
2nd: provide the QObject* parent for the contructor of CppClass when declaring it in main.cpp

load dynamic properties of a component in qml file from another qml

I have two QML files in my project.
main.qml:
Window{
width: 800
height: 500
visible: true
id:mainWinenter
Item {
id: inlinecomponent
Rectangle {
id: display
width: 50; height: 50
color: "blue"
}
}
MouseArea {
anchors.fill: parent
onClicked: {
var component = Qt.createComponent("qrc:/Test.qml");
var object = component.createObject(inlinecomponent, {"x": 50, "y": 50});
}
} }
and my Test.qml file:
Item{
id:mc
Rectangle{
x: 0
y: 0
id: rec
width: 150; height:75
color: "grey"
objectName: "recc"
visible: true
}}
main.cpp:
int main(int argc, char *argv[]){
QApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
QQuickView view;
view.setSource(QUrl("qrc:/Test.qml"));
QQuickItem *object = view.rootObject();
QObject *rect = object->findChild<QObject*>("recc");
if (rect)
rect->setProperty("color", "red");
view.show();
return app.exec();}
In main.cpp I use setProperty function to change the color of rectangle in Test.qml file. The color changes when I load the file in new window but it doesn't change when it loads in main.qml file. How I can change it when it loads in main.qml?
My output contain two windows. One for main.qml and one for Test.qml.
this is my main.qml output
this is my Test.qml output
The color of the rectangle in my Test.qml window is red but it loads grey in my main.qml. I want to load it red in main file and I want to do this with my cpp code.