2016-04-11 22 views
3

Arkadaşım ve ben C++ ve Javascript arasında iletişim kurmaya çalışıyoruz. C++/Qt (sürüm 5.6) uygulamasında gömülü olan WebGL ile belirli bir konumda bazı küreler oluşturmak istiyoruz.C++ ve Javascript arasındaki iletişim WebGL

Bunu yapmak için, WebGL için tüm JS koduna sahip bir HTML dosyasını okuyan bir QWebView kullanıyoruz. Bu iyi çalışıyor, uygulamamızın içinde harika bir üst düzey 3D renderer var. Sorun, konumun C++ tarafından bilinmesi ve JavaScript ile paylaşılması gerektiğidir.

Daha doğrusu, C++ görüntülemek için gereken kürelerin sayısını ve konumunu bilir ve bunu Javascript tarafına söylemelidir. Bunu yapmanın en iyi yolu nedir?

Not: Qt Canvas3D'yi kullanmaya çalıştık ancak klasik WebGL'ye kıyasla çok yavaştı.

DÜZENLEME 1-

deneyin ilk sonra ne yazdığını yapmak ve aynı zamanda (bu one gibi) bazı örnekler okumaya çalıştım ama o iş yapmak mümkün değil.

Tüm başlatmalarımı gerçekleştirdiğim ve verilerimi koyduğum bir QWebEngineView alt sınıfı oluşturdum.

.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 başında

#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;} 
: Ben değerini erişmek istediğiniz

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

bunu çalıştırdığınızda:

  • getNumber kez denir ve bunun QWebChannel çağrısıyla sonra gelir görünüyor
  • Ben uyarı var: Nesne 'WebGLView' arasında Property 'num'' hiçbir sinyal bildirmek etti ve sabit değil, HTML'deki değer güncellemeleri bozulacak!
  • nspherefromc, görüntülenecek kürelerin sayısıdır. 50 görüntülenir, 10 değil.

Herhangi bir fikrin var mı?

DÜZENLEME 2 - İkinci

Hala o iş yapamaz deneyin.

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

Hala var:

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

çalıştırmaya, sadece 50 var deyimi girilirse Ben bir işlev olarak adlandırılan veya olup olmadığını görmek için daha adında yeni bir değişken eklemek çalıştı küreleri. QWebChannel'deki işlev çağrılmaz. Sanırım kendim demeyi mi? Ve ne zaman ? Aynı zamanda daha fazla hata ayıklama işlemini denedim (typeof qt! = 'Undefined') sttement ve 1050 kürem var.

DÜZENLEME 3 - işlev dışında artık JSObject ulaşamadığı anlamına gelir HTML Debugger'daki

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; 

ile. Neden biliyor musun ?

DÜZENLEME - Sonunda OpenGL, C++ verileri alındığında zaten başlatılır. Bu nedenle, görüntülenen kürelerin sayısı C++'nın sorduğu değil.

+0

Qt sürümü nedir? – IAmInPLS

+0

Qt 5.6. Sorunuz için teşekkürler, açıklamayı ekledim. – ElevenJune

+0

Yanıtımı düzenledikten sonra düzenledim. – IAmInPLS

cevap

2

Qt5.6'da, iletişim kurabilmek için C++ parçası ve JavaScript yapmak istiyorsanız, bunu yapmanın tek yolu, QWebEngineView numaralı telefondan QWebChannel kullanıyor. Sadece JS tarafında satışa sunulacak TheNameOfTheObjectUsed adında bir nesneyi kayıt olduğunu söylemek, İşte

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

: Bunu .cpp dosyasında bu şekilde yapmak. Üzerinde bir yöntem olması gerekir Yani, vb küre, bazı pozisyonlarda, sayısını almak istiyorum

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

Ve sizin durumda: Şimdi, bu JS tarafında kullanmak için kod parçasıdır bir dize, bir tamsayı döndürür C++ yan uzun ... Bu yer, C++ tarafında neye benzediği senin .h:

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

Ve şimdi, bu gibi alanlarda sayısını elde JS tarafı:

var nbSpheres = JSobject.NumberOfSpheres; 

Bu çok basit bir açıklama ve bana çok faydalı olan this video'u izlemenizi öneriyorum. Ayrıca, QWebChannel tarafından sağlanan JavaScript API ve QWebChannel ile ilgili belgeler hakkında daha fazla bilgi edinmek isteyebilirsiniz;

Bu yardımcı olur umarım! senin .h olarak düzenlemenizin 1

sonra


ekleyip (veya değişim) gerekir:

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

yılında Yapıcınızda.cpp:

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

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


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

Ve JS tarafında çok önemli:

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

Ve cpp'de kendisinde

Birincisi, dikkatli olun, bunu kontrol etmeden bazı kodlar kopyalanamaz , bu yüzden Bence sen demek istedin:

if (typeof JSobject !== 'undefined') 

yerine

if (typeof widget !== 'undefined') 

Ve sonra: Artık

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

, sen JS senin değişken num değiştireceğiz zaman, bir sinyal (numChanged) yayılan edilecek ve ilgili değerini almak mümkün olacak getNumber() ile yuva.

+0

Bu çok yardımcı olur! Teşekkür ederim ! Videoyu izlemeye başladım ve şimdi deneyeceğim. Tekrar teşekkürler :) – ElevenJune

+0

Yardım etmeye sevindim :) Eğer denediğinizde başka bir sorunuz varsa, çekinmeyin! – IAmInPLS

+0

Engellemeyi yapıyorum ... Yaptığınız gibi yaptım, hatta çalışıyorum başka örnekler okumak, ama hala sorunum var. Size daha fazla kod göstermek için nasıl yaparım? Yorum yap veya düzenle – ElevenJune

İlgili konular