Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. Exchange char buffer between Qt c++ and QML
Forum Updated to NodeBB v4.3 + New Features

Exchange char buffer between Qt c++ and QML

Scheduled Pinned Locked Moved QML and Qt Quick
14 Posts 3 Posters 6.7k Views 1 Watching
  • 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.
  • R Offline
    R Offline
    Roumed
    wrote on last edited by
    #2

    You need to register types that you need.
    "Here":http://qt-project.org/doc/qt-5.1/qtqml/qtqml-cppintegration-exposecppattributes.html and "here":http://qt-project.org/doc/qt-4.8/qml-extending.html is written about this ability and similar situation.

    1 Reply Last reply
    0
    • V Offline
      V Offline
      Vincent007
      wrote on last edited by
      #3

      use QByteArray to wrap your char buffer. QByteArray object can be a property of a QObject-derived class. You should define a custom QObject-derived class that has a QByteArray property. and then register your class to QML engine.

      1 Reply Last reply
      0
      • D Offline
        D Offline
        dualfaces
        wrote on last edited by
        #4

        Thank you for your responses, I tried this and did the following:

        My class myObj which contains the buffer got a new property and methods
        @
        Q_PROPERTY(QByteArray audioBuffer READ getAudioBuffer)
        public:
        QByteArray getAudioBuffer() { return m_AudioBuffer; }
        private:
        QByteArray m_audioBuffer
        @
        Additionally, the function where i want to draw the chart was modified such that
        @
        qint64 currentSampleCount = myCustomBuffer.getSize();
        char* tmp_buf = new char[currentSampleCount];
        myCustomBuffer.read(tmp_buf, currentSampleCount);
        m_audioBuffer = QByteArray::fromRawData(tmp_buf, currentSampleCount);
        emit triggerDraw();
        @

        And my main.cpp was modified such that
        @
        QGuiApplication app(argc, argv);

        QtQuick2ApplicationViewer viewer;
        myObj obj;
        viewer.rootContext()->setContextProperty("audioData", &obj);
        viewer.setMainQmlFile(QStringLiteral("./qml/TestProject/main.qml"));
        QObject *object = viewer.rootObject();
        
        QObject::connect(&obj, SIGNAL(triggerDraw()), object, SLOT(on_drawBuffer()));
        viewer.showExpanded();
        
        
        return app.exec();
        

        @

        And in my main.qml I fetch the signal and trigger a new one which is then fetched by the chart component which simply does:
        @
        console.log("AudioBuffer has length: " + audioData.audioBuffer.length);
        @

        But the result is always undefined. What is wrong in my setup? And when i can access the audioBuffer, how to iterate over the single char elements?

        Thanks again.

        1 Reply Last reply
        0
        • R Offline
          R Offline
          Roumed
          wrote on last edited by
          #5

          bq.
          @
          qint64 currentSampleCount = myCustomBuffer.getSize();
          char* tmp_buf = new char[currentSampleCount];
          myCustomBuffer.read(tmp_buf, currentSampleCount);
          @

          First of all, you might be sure, that your sample size is 1b because of char size.
          Secondary, Is type of audioData.audioBuffer defined correctly?

          1 Reply Last reply
          0
          • D Offline
            D Offline
            dualfaces
            wrote on last edited by
            #6

            Hi,

            that the size of char is equal to 1 is assured.
            I don't get the second part of your answer.
            "audioData" is the name i used for registering the instance of myObj to the QML engine, see third listing, line 5. And audioBuffer is the property defined for myObj, see first listing line 1.

            Or do you mean something different?

            1 Reply Last reply
            0
            • R Offline
              R Offline
              Roumed
              wrote on last edited by
              #7

              Could you show result of this:
              @console.debug(audioData.audioBuffer);@
              ?
              That's what i mean - the type of audioBuffer in qml js.

              1 Reply Last reply
              0
              • D Offline
                D Offline
                dualfaces
                wrote on last edited by
                #8

                @
                console.debug("AudioBuffer" + audioData.audioBuffer);
                console.log("AudioBuffer has length: " + audioData.audioBuffer.length);
                @

                Output:
                calling getAudioBuffer
                AudioBuffer
                calling getAudioBuffer
                AudioBuffer hast length: undefined

                calling getAudioBuffer is a debug output i put into the getter MyObj::getAudioBuffer
                Does not seem to be correct, or?

                1 Reply Last reply
                0
                • R Offline
                  R Offline
                  Roumed
                  wrote on last edited by
                  #9

                  It's difficult to me to say about correctness this output because of fact that I don't know anything about way, which was presented by Vincent007.
                  But I have great doubt that QByteArray represents as nothing at QML.
                  You can try another words to get array-size, usually it may be size, count, and etc.
                  In all examples, that i've seen, QByteArray is used as binary source of data.
                  "Here":http://qt-project.org/doc/qt-5/qtqml-cppintegration-data.html there is some information about type conversion. And there is nothing about QByteArray.
                  If i was you i would try QVariant.
                  I hope you'll do it.

                  1 Reply Last reply
                  0
                  • D Offline
                    D Offline
                    dualfaces
                    wrote on last edited by
                    #10

                    Thanks for your help Roumed,

                    I am not binded to the current approach. Could you explain a few more words on the approach you mentioned in your first answer?

                    Thank you!

                    1 Reply Last reply
                    0
                    • V Offline
                      V Offline
                      Vincent007
                      wrote on last edited by
                      #11

                      If you study Qt 5 source code, you can find Q_PROPERTY(QByteArray ......

                      "Q_PROPERTY(QByteArray fragmentShader READ fragmentShader WRITE setFragmentShader NOTIFY fragmentShaderChanged)":http://code.woboq.org/qt5/qtdeclarative/src/quick/items/qquickshadereffect_p.h.html

                      Therefore, a QByteArray object can be used as a property.

                      1 Reply Last reply
                      0
                      • R Offline
                        R Offline
                        Roumed
                        wrote on last edited by
                        #12

                        Okey, this sources confirm, that QByteArray can be used as property in QML, but if we look at sources of QByteArray there are no Q_INVOKABLE methods.
                        Some blogs, forums and articles in Google says that at most cases QByteArray uses as Blob, e.g. blob contains wave. But processing of this object is hidden. So, i still have no idea how to use representation of QByteArray in QML, but i interested in it too.
                        Vincent007, could you give us an example with using count property and getting an element?

                        Dualfaces, i thought, that you have a special type to store audio data, something like AudioBuffer. So, in this case you need to make Q_INVOKABLE methods, all functionallity, that you need. In this case this object must be QObject-derived and register for qml(see "this":http://qt-project.org/doc/qt-5.1/qtqml/qtqml-cppintegration-definetypes.html#registering-c-types-with-the-qml-type-system for more information). You still can do something like this. Thats my idea, but using QByteArray is more sweet.

                        1 Reply Last reply
                        0
                        • V Offline
                          V Offline
                          Vincent007
                          wrote on last edited by
                          #13

                          QByteArray is not an QObject-derived class, so member functions of QByteArray cannot be called in QML. Workaround is needed.

                          bytearraywrapper.h
                          @
                          #ifndef BYTEARRAYWRAPPER_H
                          #define BYTEARRAYWRAPPER_H

                          #include <QObject>

                          class ByteArrayWrapper : public QObject
                          {
                          Q_OBJECT
                          Q_PROPERTY(QByteArray data MEMBER _data NOTIFY dataChanged)
                          public:
                          explicit ByteArrayWrapper(QObject *parent = 0);

                          signals:
                          void dataChanged();
                          public slots:
                          int size();
                          char at( int i ) const;
                          private:
                          QByteArray _data;
                          };

                          #endif // BYTEARRAYWRAPPER_H

                          @
                          bytearraywrapper.cpp
                          @
                          #include "bytearraywrapper.h"

                          ByteArrayWrapper::ByteArrayWrapper(QObject *parent) :
                          QObject(parent),_data("abcdefg")
                          {
                          }

                          int ByteArrayWrapper::size()
                          {
                          return _data.size();
                          }

                          char ByteArrayWrapper::at(int i) const
                          {
                          return _data.at(i);
                          }
                          @
                          in QML
                          @
                          Component.onCompleted: {
                          console.log(audioBuffer.data)
                          console.log(audioBuffer.size())
                          console.log(audioBuffer.at(3))
                          }
                          @

                          1 Reply Last reply
                          0
                          • R Offline
                            R Offline
                            Roumed
                            wrote on last edited by
                            #14

                            main.cc
                            @
                            main () {
                            QGuiApplication app(argc, argv);

                            QtQuick2ApplicationViewer viewer;
                            myObj obj;
                            

                            //! -->
                            qmlRegisterType<ByteArrayWrapper, 1>("ByteArrayWrapper", 1, 0, "CppType");
                            //! <--
                            viewer.rootContext()->setContextProperty("audioData", &obj);
                            viewer.setMainQmlFile(QStringLiteral("./qml/TestProject/main.qml"));
                            QObject *object = viewer.rootObject();

                            QObject::connect(&obj, SIGNAL(triggerDraw()), object, SLOT(on_drawBuffer()));
                            viewer.showExpanded();
                            
                            
                            return app.exec();
                            

                            }
                            @
                            And getAudioBuffer() returns ByteArrayBuffer*. This is important.
                            Thank you Vincent

                            1 Reply Last reply
                            0

                            • Login

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • Users
                            • Groups
                            • Search
                            • Get Qt Extensions
                            • Unsolved