Communication between C++ and Javascript for WebGL

后端 未结 1 1518
无人及你
无人及你 2021-01-20 06:38

My friend and I are trying to communicate between C++ and Javascript. We want to render some spheres at a given position with WebGL embedded in a C++/Qt (version 5.6) applic

相关标签:
1条回答
  • 2021-01-20 07:03

    In Qt5.6, if you want to make C++ part and JavaScript to communicate, the only way to do it is using QWebChannel on a QWebEngineView. You do it this way in the .cpp file:

    m_pView = new QWebEngineView(this);
    QWebChannel * channel = new QWebChannel(page);
    m_pView->page()->setWebChannel(channel);
    channel->registerObject(QString("TheNameOfTheObjectUsed"), this);
    

    Here, you just say that you register an object named TheNameOfTheObjectUsed that will be available on the JS side. Now, this is the part of code to use in the JS side :

    new QWebChannel(qt.webChannelTransport, function (channel) {
                // now you retrieve your object
                var JSobject = channel.objects.TheNameOfTheObjectUsed;
            });
    

    And in your case, you want to retrieve the number of spheres, some positions, etc. So you need to have a method on the C++ side which returns a string, an integer, a long... This is what it looks like on the C++ side, in your .h:

    Q_INVOKABLE int getNumberOfSpheres();
    Q_PROPERTY(int NumberOfSpheres READ getNumberOfSpheres);
    

    And now, you get the number of spheres like this on the JS side :

    var nbSpheres = JSobject.NumberOfSpheres;
    

    This is a very simple explanation, and I recommend you to watch this video which was very useful to me. Also, you might want to read more about the JavaScript API provided by QWebChannel, as well as the documentation about QWebChannel;

    Hope that helps!


    After your edit 1

    In your .h, you need to add (or change):

    int m_pNumber;
    
    Q_PROPERTY(int num READ getNumber WRITE setNumber NOTIFY numChanged)
    
    Q_INVOKABLE void setNumber(int number); // add this function to the cpp file as well
    
    //add a signal for NOTIFY
    signals:
        void numChanged();
    
    public slots:
        void numHasChanged();
    

    In your constructor in the .cpp :

    connect(this, SIGNAL(numChanged()), this, SLOT(numHasChanged()));
    

    And in the cpp itself :

    void WebGLView::setNumber(int number)
    {
        m_pNumber = number;
        emit numChanged();
    }
    
    int WebGLView::getNumber()
    {
        return m_pNumber;
    }
    
    
    void WebGLView::numHasChanged()
    {
         // do anything here
    }
    

    And very important in the JS side :

    First, be careful, you copied some code without checking it, so I think you meant :

    if (typeof JSobject !== 'undefined')
    

    instead of

    if (typeof widget !== 'undefined')
    

    And then :

    var nspherefromc =  JSobject.num; // this is ok
    var nspherefromc =  JSobject.getNumber; // this is NOT ok
    

    Now, whenever you'll change your variable num in JS, a signal will be emitted (numChanged) and you will be able to get the value in the corresponding slot with a getNumber().

    0 讨论(0)
提交回复
热议问题