From 290650aae085350e30dcbe11ea7164aa4170069c Mon Sep 17 00:00:00 2001 From: "Mehran Dehghanian (home pc)" Date: Mon, 28 Mar 2022 10:46:48 +0430 Subject: [PATCH] Added new CPPBackend data model --- CPPBackend/.gitignore | 73 ++++++++++++++++++ CPPBackend/CPPBackend.pro | 27 +++++++ CPPBackend/Home.qml | 128 +++++++++++++++++++++++++++++++ CPPBackend/applicationbridge.cpp | 45 +++++++++++ CPPBackend/applicationbridge.h | 46 +++++++++++ CPPBackend/dataobject.cpp | 38 +++++++++ CPPBackend/dataobject.h | 29 +++++++ CPPBackend/main.cpp | 29 +++++++ CPPBackend/main.qml | 23 ++++++ CPPBackend/qml.qrc | 6 ++ 10 files changed, 444 insertions(+) create mode 100644 CPPBackend/.gitignore create mode 100644 CPPBackend/CPPBackend.pro create mode 100644 CPPBackend/Home.qml create mode 100644 CPPBackend/applicationbridge.cpp create mode 100644 CPPBackend/applicationbridge.h create mode 100644 CPPBackend/dataobject.cpp create mode 100644 CPPBackend/dataobject.h create mode 100644 CPPBackend/main.cpp create mode 100644 CPPBackend/main.qml create mode 100644 CPPBackend/qml.qrc diff --git a/CPPBackend/.gitignore b/CPPBackend/.gitignore new file mode 100644 index 0000000..fab7372 --- /dev/null +++ b/CPPBackend/.gitignore @@ -0,0 +1,73 @@ +# This file is used to ignore files which are generated +# ---------------------------------------------------------------------------- + +*~ +*.autosave +*.a +*.core +*.moc +*.o +*.obj +*.orig +*.rej +*.so +*.so.* +*_pch.h.cpp +*_resource.rc +*.qm +.#* +*.*# +core +!core/ +tags +.DS_Store +.directory +*.debug +Makefile* +*.prl +*.app +moc_*.cpp +ui_*.h +qrc_*.cpp +Thumbs.db +*.res +*.rc +/.qmake.cache +/.qmake.stash + +# qtcreator generated files +*.pro.user* + +# xemacs temporary files +*.flc + +# Vim temporary files +.*.swp + +# Visual Studio generated files +*.ib_pdb_index +*.idb +*.ilk +*.pdb +*.sln +*.suo +*.vcproj +*vcproj.*.*.user +*.ncb +*.sdf +*.opensdf +*.vcxproj +*vcxproj.* + +# MinGW generated files +*.Debug +*.Release + +# Python byte code +*.pyc + +# Binaries +# -------- +*.dll +*.exe + diff --git a/CPPBackend/CPPBackend.pro b/CPPBackend/CPPBackend.pro new file mode 100644 index 0000000..224e4a5 --- /dev/null +++ b/CPPBackend/CPPBackend.pro @@ -0,0 +1,27 @@ +QT += quick + +# You can make your code fail to compile if it uses deprecated APIs. +# In order to do so, uncomment the following line. +#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 + +SOURCES += \ + applicationbridge.cpp \ + dataobject.cpp \ + main.cpp + +RESOURCES += qml.qrc + +# Additional import path used to resolve QML modules in Qt Creator's code model +QML_IMPORT_PATH = + +# Additional import path used to resolve QML modules just for Qt Quick Designer +QML_DESIGNER_IMPORT_PATH = + +# Default rules for deployment. +qnx: target.path = /tmp/$${TARGET}/bin +else: unix:!android: target.path = /opt/$${TARGET}/bin +!isEmpty(target.path): INSTALLS += target + +HEADERS += \ + applicationbridge.h \ + dataobject.h diff --git a/CPPBackend/Home.qml b/CPPBackend/Home.qml new file mode 100644 index 0000000..7a1965e --- /dev/null +++ b/CPPBackend/Home.qml @@ -0,0 +1,128 @@ +import QtQuick 2.12 +import QtQuick.Controls 2.12 +import QtQuick.Layouts 1.12 + +Flow{ + anchors.fill: parent + spacing: 0 + + //Connections + Connections{ + target: window + + onClicked1: { + console.log("Reciever","onClicked1 in connection","Do something") + } + } + + Rectangle{ + width: parent.width/2 + height: parent.height/2 + border.color: "#F5F5F5" + + ColumnLayout{ + anchors.fill: parent + + Button{ + Layout.alignment: Qt.AlignHCenter + highlighted: true + text: "Click" + + onClicked: { + window.clicked1() + ApplicationBridge.action1() + } + } + } + } + Rectangle{ + width: parent.width/2 + height: parent.height/2 + border.color: "#F5F5F5" + ColumnLayout{ + anchors.centerIn: parent + + TextField{ + id: textfield + Layout.alignment: Qt.AlignHCenter + Layout.preferredHeight: 48 + text: ApplicationBridge.inputForCpp + + onTextChanged: { + ApplicationBridge.inputForCpp= text + } + } + + Label{ + Layout.fillWidth: true + Layout.preferredWidth: textfield.width + Layout.preferredHeight: 48 + wrapMode: "WrapAnywhere" + elide: "ElideRight" + maximumLineCount: 3 + + //value + text: "C++ Property: " + ApplicationBridge.inputForCpp + } + } + } + Rectangle{ + width: parent.width/2 + height: parent.height/2 + border.color: "#F5F5F5" + ColumnLayout{ + anchors.fill: parent + + ColumnLayout{ + anchors.centerIn: parent + + Label{ + id: clockLabel + Layout.preferredHeight: 48 + wrapMode: "WrapAnywhere" + elide: "ElideRight" + maximumLineCount: 3 + + Connections{ + target: ApplicationBridge + + onTimeChanged: { + clockLabel.text= "C++ Clock: " + dateFromCPP + } + } + } + } + } + } + Rectangle{ + width: parent.width/2 + height: parent.height/2 + border.color: "#F5F5F5" + ListView{ + anchors.fill: parent + spacing: 2 + clip: true + header: Label{ + width: parent.width + text: "C++ Data model" + horizontalAlignment: "AlignHCenter" + } + + model: ApplicationBridge.list + delegate: Rectangle{ + id: modelDelegate + width: parent.width + height: 48 + color: modelData.color + + Label{ + anchors.fill: parent + text: modelData.name + horizontalAlignment: "AlignHCenter" + verticalAlignment: "AlignVCenter" + color: "white" + } + } + } + } +} diff --git a/CPPBackend/applicationbridge.cpp b/CPPBackend/applicationbridge.cpp new file mode 100644 index 0000000..c6f698b --- /dev/null +++ b/CPPBackend/applicationbridge.cpp @@ -0,0 +1,45 @@ +#include "applicationbridge.h" +#include "dataobject.h" + +ApplicationBridge::ApplicationBridge(QObject *parent) + : QObject{parent} +{ + QTimer *timer= new QTimer(this); + connect(timer, SIGNAL(timeout()), this, SLOT(timerSlot())); + timer->start(1000); + + setList({ + new DataObject("Item 1", "red"), + new DataObject("Item 2", "green"), + new DataObject("Item 3", "blue"), + new DataObject("Item 4", "yellow") + }); +} + +const QString &ApplicationBridge::inputForCpp() const +{ + return m_inputForCpp; +} + +void ApplicationBridge::setInputForCpp(const QString &newInputForCpp) +{ + if (m_inputForCpp == newInputForCpp) + return; + m_inputForCpp = newInputForCpp; + emit inputForCppChanged(); + + qWarning()<<"Set in cpp"<<" "< &ApplicationBridge::list() const +{ + return m_list; +} + +void ApplicationBridge::setList(const QList &newList) +{ + if (m_list == newList) + return; + m_list = newList; + emit listChanged(); +} diff --git a/CPPBackend/applicationbridge.h b/CPPBackend/applicationbridge.h new file mode 100644 index 0000000..dc7879d --- /dev/null +++ b/CPPBackend/applicationbridge.h @@ -0,0 +1,46 @@ +#ifndef APPLICATIONBRIDGE_H +#define APPLICATIONBRIDGE_H + +#include +#include +#include +#include +#include + +class ApplicationBridge : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString inputForCpp READ inputForCpp WRITE setInputForCpp NOTIFY inputForCppChanged) + Q_PROPERTY(QList list READ list WRITE setList NOTIFY listChanged) + +public: + explicit ApplicationBridge(QObject *parent = nullptr); + + const QString &inputForCpp() const; + void setInputForCpp(const QString &newInputForCpp); + + QString m_inputForCpp; + + //Accessible function from c++ + Q_INVOKABLE void action1(){ + qWarning()<<"Take action 1"; + } + const QList &list() const; + void setList(const QList &newList); + +signals: + void inputForCppChanged(); + void timeChanged(QDateTime dateFromCPP); + + void listChanged(); + +public slots: + void timerSlot(){ + emit timeChanged(QDateTime::currentDateTime()); + } + +private: + QList m_list; +}; + +#endif // APPLICATIONBRIDGE_H diff --git a/CPPBackend/dataobject.cpp b/CPPBackend/dataobject.cpp new file mode 100644 index 0000000..fbd5065 --- /dev/null +++ b/CPPBackend/dataobject.cpp @@ -0,0 +1,38 @@ +#include "dataobject.h" + +DataObject::DataObject(QObject *parent) + : QObject{parent} +{ +} + +DataObject::DataObject(QString name, QString color) +{ + setName(name); + setColor(color); +} + +const QString &DataObject::name() const +{ + return m_name; +} + +void DataObject::setName(const QString &newName) +{ + if (m_name == newName) + return; + m_name = newName; + emit nameChanged(); +} + +const QString &DataObject::color() const +{ + return m_color; +} + +void DataObject::setColor(const QString &newColor) +{ + if (m_color == newColor) + return; + m_color = newColor; + emit colorChanged(); +} diff --git a/CPPBackend/dataobject.h b/CPPBackend/dataobject.h new file mode 100644 index 0000000..7e7636f --- /dev/null +++ b/CPPBackend/dataobject.h @@ -0,0 +1,29 @@ +#ifndef DATAOBJECT_H +#define DATAOBJECT_H + +#include + +class DataObject : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged) + Q_PROPERTY(QString color READ color WRITE setColor NOTIFY colorChanged) +public: + explicit DataObject(QObject *parent = nullptr); + explicit DataObject(QString name, QString color); + + const QString &name() const; + void setName(const QString &newName); + + const QString &color() const; + void setColor(const QString &newColor); + + QString m_name; + QString m_color; +signals: + + void nameChanged(); + void colorChanged(); +}; + +#endif // DATAOBJECT_H diff --git a/CPPBackend/main.cpp b/CPPBackend/main.cpp new file mode 100644 index 0000000..bf4d3ba --- /dev/null +++ b/CPPBackend/main.cpp @@ -0,0 +1,29 @@ +#include +#include +#include +#include "applicationbridge.h" + +int main(int argc, char *argv[]) +{ +#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0) + QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); +#endif + QGuiApplication app(argc, argv); + + ApplicationBridge appBridgeObject; + + QQmlApplicationEngine engine; + + //Register c++ class to qml + engine.rootContext()->setContextProperty("ApplicationBridge", &appBridgeObject); + + 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(); +} diff --git a/CPPBackend/main.qml b/CPPBackend/main.qml new file mode 100644 index 0000000..afa97dd --- /dev/null +++ b/CPPBackend/main.qml @@ -0,0 +1,23 @@ +import QtQuick 2.12 +import QtQuick.Window 2.12 +import QtQuick.Layouts 1.12 + +//Window is accessible from everwhere, so we can use 'window' everywhere +Window { + id: window + width: 640 + height: 480 + visible: true + title: qsTr("CPP Backend") + + //Signal + signal clicked1() + + onClicked1: { + console.log("Reciever","onClicked1","Do something") + } + + Home{ + + } +} diff --git a/CPPBackend/qml.qrc b/CPPBackend/qml.qrc new file mode 100644 index 0000000..ef59762 --- /dev/null +++ b/CPPBackend/qml.qrc @@ -0,0 +1,6 @@ + + + main.qml + Home.qml + +