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.
  • D Offline
    D Offline
    dualfaces
    wrote on 4 Feb 2014, 14:52 last edited by
    #1

    Hello,

    I am quite new to QML and face a problem when trying to draw a chart from a char buffer.
    I use QML as GUI frontend and connect the backend application written in Qt C++ via signals and slots to the UI.
    This works fine for primitive types. There i use a signal in my app like newDataAvailable(QVariant data), connect it to a function in my main.qml which then forwards the data by emitting signals that are fetched by the respective components. But i don't know how to exchange more involved types.
    I have a buffer of audio data which needs to be displayed from time to time in the UI. Therefore i made a Chart Component with the respective drawing logic using canvas.
    But how can i forward the data from the application to the UI, such that it is available for drawing?

    This question is quite vague, but I hope you get my problem.

    Thank you for your help!

    Kind regards

    1 Reply Last reply
    0
    • R Offline
      R Offline
      Roumed
      wrote on 4 Feb 2014, 15:30 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 4 Feb 2014, 15:43 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 5 Feb 2014, 07:16 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 5 Feb 2014, 07:42 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 5 Feb 2014, 07:51 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 5 Feb 2014, 07:55 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 5 Feb 2014, 08:00 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 5 Feb 2014, 09:21 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 5 Feb 2014, 10:11 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 5 Feb 2014, 12:57 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 5 Feb 2014, 17:57 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 6 Feb 2014, 14:18 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 6 Feb 2014, 15:00 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

                              1/14

                              4 Feb 2014, 14:52

                              • Login

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