2016-04-11 26 views
3

私の友人と私はC++とJavascriptの間の通信を試みています。 C++/Qt(バージョン5.6)アプリケーションに埋め込まれたWebGLを使用して、特定の位置にいくつかの球体を描画したいとします。WebGLのC++とJavascript間の通信

これを行うには、QWebViewを使用して、WebGLのすべてのJSコードを含むHTMLファイルを読み取ります。これはうまくいく、私たちのアプリケーションの中に素晴らしい高レベルの3Dレンダラーがあります。 問題は、位置がC++によって認識され、JavaScriptと共有される必要があることです。

より正確には、C++は、表示する必要がある球の数とその位置を知り、Javascript側に伝えなければなりません。それをする最善の方法は何ですか?

注:Qt Canvas3Dを使用しようとしましたが、従来のWebGLと比較して遅すぎました。

EDIT 1 - 最初の試みの後

私はあなたが書いた何も(このoneのような)いくつかの例を読み取ろうとしましたが、私はそれを動作させることはできません。

QWebEngineViewのサブクラスを作成しました。ここで私はすべての初期化を行い、データを入れます。

.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:JSの開始時に

#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; 
} 

if (typeof widget !== 'undefined') { 
    var nspherefromc = JSobject.getNumber; 
} else {var nspherefromc = 50;} 
:私は値にアクセスしたい

<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; 
}); 

私はそれを実行します。

  • はgetNumberを一度と呼ばれ、QWebChannel
  • を呼び出した後、私は警告していくるものと思われます:プロパティ「NUM」」オブジェクトの 『のWebGLView』は信号を通知していません定数ではない場合、HTMLの値の更新は壊れます!
  • nspherefromcは、表示される球の数です。 50は表示されますが、10は表示されません。

アイデアはありますか?

EDIT 2 - 第二に、私はまだそれを動作させることができない

を試してみてください。 私は文が入力された場合、新しい関数が呼び出されるかどうかを確認するために、よりという名前の変数またはAを追加しようとしました:

var more = 0; 
     if (typeof qt != 'undefined') { 
      new QWebChannel(qt.webChannelTransport, function(channel) { 
       JSobject = channel.objects.test; 
       more = 1000; 
      } 
      ); 
     } 

私はまだ持っている:

if (typeof JSobject !== 'undefined') { 
     nspherefromc = JSobject.num; 
    } 
    else {nspherefromc = 50;} 
    ... 
    var spheresNum = nspherefromc + more;//Number of Spheres 

それを実行しているとき、私は50を持っています球体。 QWebChannel内の関数は呼び出されません。私はそれを私自身と呼ぶと思いますか?いつ? また、if(typeof qt!= 'undefined')ステートメントでさらにデバッグしようとしましたが、1050個の球があります。

EDIT 3 - 関数の外で私はもうのJSObjectに到達できないことを意味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; 

付き。なぜなのかご存知ですか ?

EDIT - 最後に OpenGLは、C++からのデータを受信すると既に初期化されています。したがって、表示される球の数はC++に求められる数ではありません。

+0

Qtのどのバージョン? – IAmInPLS

+0

Qt5.6。あなたの質問をありがとう、私は説明に追加しました。 – ElevenJune

+0

あなたの編集に続いて自分の答えを編集しました。 – IAmInPLS

答えて

2

Qt5.6では、C++の部分とJavaScriptを通信するには、QWebEngineViewQWebChannelを使用する唯一の方法があります。あなたはちょうどあなたがJS側で利用できるようになりますTheNameOfTheObjectUsedという名前のオブジェクトを登録することを言い、ここで

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

:あなたはそれ.cppファイル内でこのようください。さて、これは、JS側に使用するコードの一部です:

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

そして、あなたの場合には、あなたは、などの球の数、いくつかの位置を取得したいので、あなたは上のメソッドを持っている必要があります文字列、整数を返すC++側は、長い...これは、それはあなたの.hで、C++側で次のようになります。

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

そして今、あなたは上でこのような球の数を取得しますJS側:

var nbSpheres = JSobject.NumberOfSpheres; 

これは非常に簡単な説明で、私には非常に便利だったthis videoを見ることをお勧めします。また、QWebChannelが提供するJavaScript APIについての詳細や、QWebChannelに関するドキュメントを読むこともできます。

希望に役立ちます!あなたの.hで


あなたの編集後

、あなたは追加(または変更)する必要がありますで、あなたのコンストラクタで

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(); 

。CPP:

void WebGLView::setNumber(int number) 
{ 
    m_pNumber = number; 
    emit numChanged(); 
} 

int WebGLView::getNumber() 
{ 
    return m_pNumber; 
} 


void WebGLView::numHasChanged() 
{ 
    // do anything here 
} 

そして、JS側で非常に重要:

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

そしてCPP自体で

まず、注意してください、あなたはそれをチェックせずにいくつかのコードをコピーし ので、私はあなたが意味すると思う:

if (typeof JSobject !== 'undefined') 

の代わりに

if (typeof widget !== 'undefined') 

そして:今すぐ

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

、あなたはJSでの変数numを変更しますいつでも、信号は(numChanged)が放出されると、あなたは相当の値を取得することができますスロットはgetNumber()です。

+0

それは多くの助けて!ありがとうございました ! 私はビデオを見始めて、今私はそれを試してみるつもりです。再度ありがとう:) – ElevenJune

+0

喜んで:)あなたがそれを試してみるときに他の質問があれば、躊躇しないでください! – IAmInPLS

+0

私はブロックしています... 私はあなたがしたように、私は動作する他の例を読んでも、私はまだ問題があります。 さらにコードを表示するにはどうすればよいですか?コメントや編集は? – ElevenJune

関連する問題