Mon ami et moi essayons de communiquer entre C++ et Javascript. Nous voulons rendre certaines sphères à une position donnée avec WebGL incorporé dans une application C++/Qt (version 5.6).Communication entre C++ et Javascript pour WebGL
Pour ce faire, nous utilisons un QWebView
qui lit un fichier HTML avec tout le code JS pour WebGL. Cela fonctionne bien, nous avons un bon moteur de rendu 3D de haut niveau dans notre application. Le problème est que la position est connue par le C++ et doit être partagée avec le JavaScript.
Plus précisément, le C++ connaît le nombre de sphères que nous devons afficher et leur position, et doit le dire du côté Javascript. Quelle est la meilleure façon de le faire?
Remarque: Nous avons essayé d'utiliser Qt Canvas3D, mais il était trop lent par rapport au WebGL classique.
EDIT 1 - Après le premier essai
j'ai essayé de faire ce que vous avez écrit et lu aussi quelques exemples (comme celui-ci one) mais je ne peux pas le faire fonctionner.
J'ai créé une sous-classe de QWebEngineView où je fais toutes mes initialisations et met mes données.
.h:
#ifndef WEBGLVIEW_H
#define WEBGLVIEW_H
#include <QObject>
#include <QtWebEngineWidgets>
#include <QtWebChannel/QtWebChannel>
class WebGLView : public QWebEngineView
{
Q_OBJECT
Q_INVOKABLE int getNumber();
Q_PROPERTY(int num READ getNumber)
public:
WebGLView(QWidget *parent = 0);
private :
QWebChannel* m_channel;
};
#endif // WEBGLVIEW_H
Cpp:
#include "WebGLView.h"
#include <QCoreApplication>
#include <QUrl>
#include <QDebug>
WebGLView::WebGLView(QWidget *parent) :
QWebEngineView(parent)
{
// Set up the communications channel
//C++ to Java test
m_channel = new QWebChannel(this);
this->page()->setWebChannel(m_channel);
m_channel->registerObject(QString("test"),this);
QString path = QCoreApplication::applicationDirPath() + "/test6.html";
this->setUrl(QUrl::fromLocalFile(path));
}
int WebGLView::getNumber()
{
qDebug() << "getNumber";
return 10;
}
Au début de la JS:
<script type="text/javascript" src="qrc:///qtwebchannel/qwebchannel.js"></script>
...
var JSobject;
if (typeof qt != 'undefined') {new QWebChannel(qt.webChannelTransport, function(channel) {
JSobject = channel.objects.test;
});
Lorsque je veux accéder à la valeur:
if (typeof widget !== 'undefined') {
var nspherefromc = JSobject.getNumber;
} else {var nspherefromc = 50;}
Quand je le lance:
- getNumber est appelé une fois, et il semble que cela vient après un appel à QWebChannel
- Je avertissement: la propriété « num » » de l'objet « WebGLView » a notifier aucun signal et n'est pas constante, les mises à jour de valeur en HTML seront brisées!
- nspherefromc est le nombre de sphères qui seront affichées. 50 sont affichés, pas 10.
Des idées?
EDIT 2 - Deuxième essai
Je ne peux toujours pas le faire fonctionner. J'ai essayé d'ajouter une nouvelle variable nommée plus pour voir si une fonction est appelée ou une instruction if est entré:
var more = 0;
if (typeof qt != 'undefined') {
new QWebChannel(qt.webChannelTransport, function(channel) {
JSobject = channel.objects.test;
more = 1000;
}
);
}
j'ai encore:
if (typeof JSobject !== 'undefined') {
nspherefromc = JSobject.num;
}
else {nspherefromc = 50;}
...
var spheresNum = nspherefromc + more;//Number of Spheres
Lors de l'exécution, je n'ai que 50 sphères. La fonction dans QWebChannel n'est pas appelée. Je suis supposé l'appeler moi-même? Et quand ? J'ai aussi essayé le plus de débogage dans le sttement if (typeof qt! = 'Undefined') et j'ai 1050 sphères.
EDIT 3 - Avec un Debugger HTML
function init() {
var JSobject;
var nspherefromc = 0;
if (typeof qt !== 'undefined') {
new QWebChannel(qt.webChannelTransport, function(channel) {
JSobject = channel.objects.test;
console.log(JSobject); //-> returns the object, I can access the functions and everything
nspherefromc = JSobject.num;
console.log("in the function " + nspherefromc); //prints 5000, what i sent from C++
more = 1000;
}
);
console.log(JSobject); // prints undefined
}
console.log(JSobject); // prints undefined
if (typeof JSobject !== 'undefined') {
console.log("Yeaaaah"); //Not reached
nspherefromc = JSobject.num;
nspherefromc + 1;
}
...
console.log("when loading " + nspherefromc + " (more is = to " + more); // nsphere = 0 , more = 0
var spheresNum = nspherefromc + more;
Ce qui signifie que, en dehors de la fonction, je ne peut pas atteindre JSObject plus. Est-ce que tu sais pourquoi ?
EDIT - À la fin L'OpenGL est déjà initialisé lorsque les données du C++ sont reçues. Par conséquent, le nombre de sphères affichées n'est pas celui demandé par le C++.
Quelle version de Qt? – IAmInPLS
Qt 5.6. Merci pour votre question, je l'ai ajouté dans la description. – ElevenJune
J'ai édité ma réponse suite à votre modification. – IAmInPLS