Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Solved Integrating QtQuick with c++ code

    QML and Qt Quick
    qtquick c++11
    3
    9
    3714
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • C
      clarity last edited by

      Hello,

      I'm new to Qt, and I'm having trouble integrating c++ with QtQuick

      When I call the next button, I want to display the text "test123" in the block TextArea from c++.

      Here's the code I have:

      main.cpp:
      #include <QApplication>
      #include <QQmlApplicationEngine>

      int main(int argc, char *argv[])
      {
      QApplication app(argc, argv);

      QQmlApplicationEngine engine;
      engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
      
      return app.exec();
      

      }

      main.qml:
      import QtQuick 2.5
      import QtQuick.Controls 1.4
      import QtQuick.Dialogs 1.2

      ApplicationWindow {
      visible: true
      width: 640
      height: 480
      title: qsTr("Hello World")

      menuBar: MenuBar {
          Menu {
              title: qsTr("File")
              MenuItem {
                  text: qsTr("&Open")
                  onTriggered: console.log("Open action triggered");
              }
              MenuItem {
                  text: qsTr("Exit")
                  onTriggered: Qt.quit();
              }
          }
      }
      
      MainForm {
          anchors.fill: parent
          button1.onClicked: block.text = "test"
          button2.onClicked: messageDialog.show(qsTr("Button 2 pressed"))
      }
      
      MessageDialog {
          id: messageDialog
          title: qsTr("May I have your attention, please?")
      
          function show(caption) {
              messageDialog.text = caption;
              messageDialog.open();
          }
      }
      

      }

      MainForum.ui.qml:
      import QtQuick 2.5
      import QtQuick.Controls 1.4
      import QtQuick.Layouts 1.2

      Item {
      width: 640
      height: 480

      property alias button1: previous
      property alias button2: next
      property alias block: block
      
      RowLayout {
          anchors.verticalCenterOffset: 214
          anchors.horizontalCenterOffset: 1
          anchors.centerIn: parent
      
          Button {
              id: previous
              text: qsTr("Previous")
          }
      
          Button {
              id: next
              text: qsTr("Next")
          }
      }
      
      TextArea {
          id: block
          x: 72
          y: 8
          width: 498
          height: 421
          visible: true
          frameVisible: true
          tabChangesFocus: false
          readOnly: true
      }
      

      }

      Thanks,
      Ryan

      1 Reply Last reply Reply Quote 0
      • Charby
        Charby last edited by

        First you should register your C++ class or object to the Quick engine, as follow :

        • register your class from your main.cpp:
        qmlRegisterType<QMyObject>("QMyObject", 1, 0, "QMyObject");
        
        • pass your object as a property of the engine context, from your main.cpp :
        QMyObject myObject;
        engine.rootContext()->setContextProperty("myObject", &myObject);
        

        From now on, your C++ will be available from your QML...

        • If you registered your class, you will be able to add qml Element of your class from you main.qml :
        import QMyObject 1.0
        QMyObject{
        }
        
        • if you passed your object as a property, from your QML you simply will have your "myObject" available as QML element...

        Then you have several option to achieve your purpose, you can either :

        • connect your button signal to your QMyObject slot
        • define a string property into you QMyObject that will contains what you want to show - and defines your TextArea.text to use it
        1 Reply Last reply Reply Quote 0
        • C
          clarity last edited by

          Thanks for the response!

          I'm having some trouble getting qmlRegisterType to work.

          here's my main.cpp:
          #include <QApplication>
          #include <QQmlApplicationEngine>

          #include <test.h>

          int main(int argc, char *argv[])
          {
          QApplication app(argc, argv);

          QQmlApplicationEngine engine;
          engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
          
          qmlRegisterType<Test>("Test", 1, 0, "Test");
          
          return app.exec();
          

          }

          I'm getting compile the following compile time errors:

          ../test/main.cpp:13:5: error: use of undeclared identifier 'qmlRegisterType'
          qmlRegisterType<Test>("Test", 1, 0, "Test");

          Do I need to include something to get access to qmlRegisterType?

          1 Reply Last reply Reply Quote 0
          • C
            clarity last edited by

            including QtQml fixed the issue with qmlRegisterType

            Still working on getting the other stuff working

            1 Reply Last reply Reply Quote 0
            • C
              clarity last edited by

              Is there a way to connect c++ to qml? Like a class signal to the qml slot?

              Thanks,
              Ryan

              raven-worx Charby 2 Replies Last reply Reply Quote 0
              • raven-worx
                raven-worx Moderators @clarity last edited by

                @clarity
                Read this to publish a C++ QObject to QML.
                Then you can bind it's properties to any QML property.
                Important is that the QObject uses the Q_PROPERTY macro specifying a change-signal (using NOTIFY in the property macro).
                And of course make sure you call this signal whenever the value of the property changes (best in the setter method of the property)

                --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
                If you have a question please use the forum so others can benefit from the solution in the future

                1 Reply Last reply Reply Quote 0
                • Charby
                  Charby @clarity last edited by

                  @clarity if you need to react on QML from a signal emitted in your c++ object, you can simply use this in your QML file : (considering you have added myObject as context property - as mentioned earlier - and your objects emits a signal mySignal)

                  Connections{
                        target:myObject
                        onMySignal: ///do whatever you need
                   }
                  
                  1 Reply Last reply Reply Quote 0
                  • C
                    clarity last edited by

                    I'm getting an error when I run the code below. The error is: qrc:/main.qml:34:21: Unable to assign [undefined] to String

                    Here's the code!

                    test.h:
                    #ifndef TEST_H
                    #define TEST_H

                    #include <QObject>

                    class Test : public QObject
                    {
                    Q_OBJECT
                    Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)

                    public:
                    explicit Test(QObject *parent = 0);
                    QString text() const;
                    void setText(QString txt);

                    signals:
                    void textChanged();

                    public slots:
                    void testSlot();

                    protected:
                    QString m_text = "Not Set";
                    };

                    #endif // TEST_H

                    test.c:
                    #include "test.h"

                    #include <QDebug>

                    using namespace std;

                    Test::Test(QObject *parent) : QObject(parent)
                    {
                    }

                    void Test::testSlot() {
                    qDebug() << "Test::testSlot called" << endl;
                    this->setText("test slot called");
                    }

                    QString Test::text() const {
                    return this->m_text;
                    }

                    void Test::setText(QString txt) {
                    this->m_text = txt;
                    emit textChanged();
                    }

                    main.c:
                    #include <QApplication>
                    #include <QQmlApplicationEngine>

                    #include <QtQml>

                    #include <test.h>

                    int main(int argc, char *argv[])
                    {
                    QApplication app(argc, argv);

                    qmlRegisterType<Test>("Test", 1, 0, "Test");
                    
                    QQmlApplicationEngine engine;
                    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
                    
                    Test t;
                    
                    engine.rootContext()->setContextProperty("Test", &t);
                    
                    QObject *item = engine.rootObjects().at(0);
                    
                    QObject::connect(item, SIGNAL(buttonPressed()),
                                     &t, SLOT(testSlot()));
                    
                    return app.exec();
                    

                    }

                    main.qml:
                    import QtQuick 2.5
                    import QtQuick.Controls 1.4
                    import QtQuick.Dialogs 1.2

                    import Test 1.0

                    ApplicationWindow {
                    id: mainWindow
                    visible: true
                    width: 640
                    height: 480
                    title: qsTr("Hello World")

                    signal buttonPressed();
                    
                    menuBar: MenuBar {
                        Menu {
                            title: qsTr("File")
                            MenuItem {
                                text: qsTr("&Open")
                                onTriggered: console.log("Open action triggered");
                            }
                            MenuItem {
                                text: qsTr("Exit")
                                onTriggered: Qt.quit();
                            }
                        }
                    }
                    
                    MainForm {
                        anchors.fill: parent
                        button1.onClicked: block.text = "prev clicked"
                        button2.onClicked: mainWindow.buttonPressed()
                        block.text: Test.text
                    }
                    
                    MessageDialog {
                        id: messageDialog
                        title: qsTr("May I have your attention, please?")
                    
                        function show(caption) {
                            messageDialog.text = caption;
                            messageDialog.open();
                        }
                    }
                    

                    }

                    Thanks!

                    1 Reply Last reply Reply Quote 0
                    • C
                      clarity last edited by

                      I went on #qt-quick on free node, and w00t helped me.

                      Here's the fixed code:

                      test.h:
                      #ifndef TEST_H
                      #define TEST_H

                      #include <QObject>

                      class Test : public QObject
                      {
                      Q_OBJECT
                      Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)

                      public:
                      explicit Test(QObject *parent = 0);
                      QString text() const;
                      void setText(QString txt);

                      signals:
                      void textChanged();

                      public slots:
                      void testSlot();

                      protected:
                      QString m_text = "Default String";
                      };

                      #endif // TEST_H

                      test.cpp:
                      #include "test.h"

                      #include <QDebug>

                      using namespace std;

                      Test::Test(QObject *parent) : QObject(parent)
                      {
                      }

                      void Test::testSlot() {
                      qDebug() << "Test::testSlot called" << endl;
                      this->setText("test slot called");
                      }

                      QString Test::text() const {
                      return this->m_text;
                      }

                      void Test::setText(QString txt) {
                      this->m_text = txt;
                      emit textChanged();
                      }

                      main.cpp:
                      #include <QApplication>
                      #include <QQmlApplicationEngine>

                      #include <QtQml>

                      #include <test.h>

                      int main(int argc, char *argv[])
                      {
                      QApplication app(argc, argv);

                      QQmlApplicationEngine engine;
                      
                      Test t;
                      
                      engine.rootContext()->setContextProperty("Test", &t);
                      
                      engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
                      
                      QObject *item = engine.rootObjects().at(0);
                      
                      QObject::connect(item, SIGNAL(buttonPressed()),
                                       &t, SLOT(testSlot()));
                      
                      
                      
                      return app.exec();
                      

                      }

                      main.qml:
                      import QtQuick 2.5
                      import QtQuick.Controls 1.4
                      import QtQuick.Dialogs 1.2

                      ApplicationWindow {
                      id: mainWindow
                      visible: true
                      width: 640
                      height: 480
                      title: qsTr("Hello World")

                      signal buttonPressed();
                      
                      menuBar: MenuBar {
                          Menu {
                              title: qsTr("File")
                              MenuItem {
                                  text: qsTr("&Open")
                                  onTriggered: console.log("Open action triggered");
                              }
                              MenuItem {
                                  text: qsTr("Exit")
                                  onTriggered: Qt.quit();
                              }
                          }
                      }
                      
                      MainForm {
                          anchors.fill: parent
                          button1.onClicked: block.text = "prev clicked"
                          button2.onClicked: mainWindow.buttonPressed()
                          block.text: Test.text
                      }
                      
                      MessageDialog {
                          id: messageDialog
                          title: qsTr("May I have your attention, please?")
                      
                          function show(caption) {
                              messageDialog.text = caption;
                              messageDialog.open();
                          }
                      }
                      

                      }

                      Thanks everyone!

                      1 Reply Last reply Reply Quote 0
                      • First post
                        Last post