├── qml.qrc ├── README.md ├── counter.cpp ├── counter.h ├── qml_cpp_signal_example.pro ├── main.cpp └── main.qml /qml.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | main.qml 4 | 5 | 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![screenshot](https://raymii.org/s/inc/img/qtqml-example.png) 2 | 3 | See here: https://raymii.org/s/snippets/Cpp_QT_QML_Signals_and_Slots.html 4 | -------------------------------------------------------------------------------- /counter.cpp: -------------------------------------------------------------------------------- 1 | #include "counter.h" 2 | 3 | Counter::Counter(QObject* parent) : QObject(parent) 4 | { 5 | } 6 | 7 | void Counter::setValue(long long value) { 8 | if (value == m_Value) 9 | return; 10 | m_Value = value; 11 | emit valueChanged(value); 12 | } 13 | -------------------------------------------------------------------------------- /counter.h: -------------------------------------------------------------------------------- 1 | #ifndef COUNTER_H 2 | #define COUNTER_H 3 | 4 | #include 5 | 6 | class Counter : public QObject 7 | { 8 | Q_OBJECT 9 | Q_PROPERTY(long long value READ value WRITE setValue NOTIFY valueChanged) 10 | public: 11 | explicit Counter(QObject *parent = nullptr); 12 | long long value() { return m_Value; }; 13 | 14 | public slots: 15 | void setValue(long long value); 16 | 17 | signals: 18 | void valueChanged(long long newValue); 19 | 20 | private: 21 | long long m_Value {0} ; 22 | }; 23 | 24 | #endif // COUNTER_H 25 | -------------------------------------------------------------------------------- /qml_cpp_signal_example.pro: -------------------------------------------------------------------------------- 1 | QT += quick 2 | 3 | CONFIG += c++11 4 | 5 | # You can make your code fail to compile if it uses deprecated APIs. 6 | # In order to do so, uncomment the following line. 7 | #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0 8 | 9 | SOURCES += \ 10 | counter.cpp \ 11 | main.cpp 12 | 13 | RESOURCES += qml.qrc 14 | 15 | # Additional import path used to resolve QML modules in Qt Creator's code model 16 | QML_IMPORT_PATH = 17 | 18 | # Additional import path used to resolve QML modules just for Qt Quick Designer 19 | QML_DESIGNER_IMPORT_PATH = 20 | 21 | # Default rules for deployment. 22 | qnx: target.path = /tmp/$${TARGET}/bin 23 | else: unix:!android: target.path = /opt/$${TARGET}/bin 24 | !isEmpty(target.path): INSTALLS += target 25 | 26 | HEADERS += \ 27 | counter.h 28 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "counter.h" 6 | 7 | 8 | int main(int argc, char *argv[]) 9 | { 10 | 11 | 12 | QGuiApplication app(argc, argv); 13 | 14 | QQmlApplicationEngine engine; 15 | Counter myCounter; 16 | 17 | QQmlContext *context = engine.rootContext(); 18 | /* Below line makes myCounter object and methods available in QML as "MyCounter" */ 19 | context->setContextProperty("MyCounter", &myCounter); 20 | 21 | const QUrl url(QStringLiteral("qrc:/main.qml")); 22 | QObject::connect(&engine, &QQmlApplicationEngine::objectCreated, 23 | &app, [url](QObject *obj, const QUrl &objUrl) { 24 | if (!obj && url == objUrl) 25 | QCoreApplication::exit(-1); 26 | }, Qt::QueuedConnection); 27 | 28 | 29 | engine.load(url); 30 | 31 | return app.exec(); 32 | 33 | 34 | } 35 | -------------------------------------------------------------------------------- /main.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.11 2 | import QtQuick.Window 2.11 3 | import QtQuick.Controls 2.11 4 | 5 | Window { 6 | width: 640 7 | height: 480 8 | visible: true 9 | title: qsTr("QML Signals and slots example - Raymii.org") 10 | 11 | MenuBar { 12 | width: parent.width 13 | Menu { 14 | title: qsTr("File") 15 | MenuItem { 16 | text: qsTr("Exit") 17 | onTriggered: Qt.quit(); 18 | } 19 | } 20 | } 21 | 22 | Column { 23 | anchors.horizontalCenter: parent.horizontalCenter 24 | anchors.verticalCenter: parent.verticalCenter 25 | spacing: 20 26 | 27 | Text { 28 | id: info 29 | width: parent.width * 0.9 30 | wrapMode: Text.WordWrap 31 | text: "QML / C++ binding via signals and slots example program, by Raymii.org. License: GNU GPLv3" 32 | } 33 | 34 | 35 | Text { 36 | id: labelCount 37 | // C++ method Counter::value(). Bound via Q_PROPERTY, updates automatically on change 38 | text: "Counter: " + MyCounter.value + "." 39 | } 40 | 41 | Text { 42 | property int changeCount: 0 43 | id: labelChanged 44 | text: "Count has changed " + changeCount + " times." 45 | // Receive the valueChanged NOTIFY 46 | Connections { 47 | target: MyCounter 48 | onValueChanged: { 49 | ++labelChanged.changeCount 50 | } 51 | } 52 | } 53 | 54 | Row { 55 | spacing: 20 56 | Button { 57 | text: qsTr("Increase Counter") 58 | onClicked: ++MyCounter.value 59 | } 60 | 61 | Button { 62 | text: qsTr("Set counter to 10") 63 | // C++ method Counter::setValue(int), bound via Q_PROPERTY 64 | onClicked: MyCounter.setValue(10) 65 | 66 | } 67 | Button { 68 | text: qsTr("Reset") 69 | onClicked: { 70 | // C++ method Counter::setValue(int), bound via Q_PROPERTY 71 | MyCounter.setValue(0) 72 | } 73 | } 74 | } 75 | 76 | Row { 77 | spacing: 20 78 | 79 | Text { 80 | id: setText 81 | text: qsTr("Enter counter value: ") 82 | } 83 | Rectangle { 84 | width: setText.width 85 | height: setText.height 86 | border.width: 1 87 | border.color: "black" 88 | 89 | TextInput { 90 | id: counterInput 91 | focus: true 92 | text: MyCounter.value 93 | } 94 | } 95 | // Bi-directional binding, entering a number in the textarea updates the 96 | // C++ class, if the C++ class is updated, the textarea is updated as well. 97 | Binding { 98 | target: MyCounter 99 | property: "value" 100 | value: counterInput.text 101 | } 102 | } 103 | } 104 | } 105 | 106 | --------------------------------------------------------------------------------