2009-06-03 6 views
6

addToJavaScriptWindowObject, というQWebFrameにC++オブジェクトを追加して、そのオブジェクトのスロットをjavascriptから呼び出すことができました。QWebViewでJavascriptを取得してC++ベースのクラスの新しいインスタンスを作成するにはどうすればいいですか?

私が本当にやりたいことは、それらのスロットの1つに新しいオブジェクトを返すことです。例えば、私はQObjectの派生クラスのインスタンスを返します。このようなスロット、持っている:

MyObject* MyApp::helloWorld() 
    { 
      //MyObject is dervied from QObject 
      return new MyObject(); 
    } 

を私は正常にこの

var foo=myapp.helloWorld(); 

のようにJavaScriptからこのスロットを呼び出すことができますしかし、fooが空のように見える、I任意のスロットを呼び出すことはできません。または、 のプロパティにJavascriptからアクセスすることはできません。

私はこれをどのように達成することができますか?

+0

MyApp :: helloWorldの意味ですか? – jrharshath

+0

はい、よく見つけました:) –

答えて

4

私が考えられてきたワンむしろ醜いハックはその後、私のスロットではなく、オブジェクトのインスタンスの名前を返してきた、私はランダムな名前を持つウィンドウオブジェクトに返すようにしたいオブジェクトをドロップするaddToJavaScriptWindowObjectを使用することです:

QString MyApp::helloWorld() 
{ 
    //general a unique name for the js variable 
    QString name=getRandomVariableName(); 

    //here's the object we want to expose to js 
    MyObject* pReturn=new MyObject(); 

    //we make attach our object to the js window object  
    getWebFrame()->addToJavaScriptWindowObject(name, pReturn, 
     QScriptEngine::ScriptOwnership); 

    //tell js the name we used 
    return name; 
} 

JSは、戻り値が文字列であるかどうかを確認するために書かれ、それがある場合、ウィンドウからオブジェクトをつかむ:

var foo=myapp.helloWorld(); 
if (typeof foo == "string") 
{ 
    foo=window[foo]; 
} 

少し醜い、より良いするまで私を取得することができます方法は来る。将来のQtバージョンではスクリプトサポートが統一され、WebKitのJavaScriptCoreに基づいていますので、うまくいけば改善されます!

1

QtScriptには、プロトタイプという概念があります。これにより、スクリプト値のC++プロトタイプを作成できます。 の場合、WebKitのJavaScript環境のプロトタイプを使用する可能性があります。この場合、JavaScriptCoreを使用してQtScriptをブリッジすることができます。 http://doc.trolltech.com/4.5/qtscript.html#making-use-of-prototype-based-inheritance

+0

はい、私はいくつかの統一がロードマップにあることを知っていました。とにかく私の回避策の「醜さ」を隠すために私は挑戦しました。私が書いたjsは、より良い解決策が生まれても大部分は使えるままです。 –

1

新しいオブジェクトをMyObject *ではなくQObject *として返してください。 QtScriptを使って作業しているだけの場合は、qScriptRegisterMetaTypeを呼び出してMyObject *をQScriptValues(またはQVariants)に変換する処理を行うコードを定義できますが、QtWebKitで使用されているJavaScriptエンジンと同等のものはありません。

これは、内部オブジェクトモデルをWebKitに公開するには、オブジェクトポインタをQObject *に変換する別の一連のプロキシ関数を使用すること、または同じ種類のアダプタクラスを使用することが含まれることを意味します。

+0

確かに、私はC++とJSの両方のアダプタクラスを使ってギャップを埋めることができ、実際のJSのようにすべてがうまくいっているように感じさせます。 –

2

オブジェクトポインタをQObject *に割り当てて返すことができます。

QObject * obj = new MyObject(); 
    return obj; 

LinuxのQt Webkitポートで動作しています。

0

この回答はPaulの答えに基づいていますが、少し簡略化されています。 Qt 5.3で動作確認済みです。オブジェクトをインスタンス化するファクトリが必要です。次にQObjectポインタをこのオブジェクトに返します。オブジェクトのクラスは、それがJavaScriptで正常に動作するようにQObjectから継承しています。これにより

QObject * MyApp::createInstance(QString objname) { 
    MyClass * obj = new MyClass(this); 
    m_mainWindow->webView->page()->mainFrame()->addToJavaScriptWindowObject(objname, obj, QWebFrame::ScriptOwnership); 
    return obj; 
} 

を、あなたはJavascriptから次の操作を行うことができます。この時点で

var myobject = MyApp.createInstance("obj1"); 

を、あなたにもobj1を持っていますで

myobject.testmethod(); 
obj1.testmethod(); 

:グローバルJavaScript名前空間でmyobject(彼らはポインタなので、次の作品の両方を行うこととしてここでは、JavaScriptでconnectを使用して、C++シグナルをJavaScriptスロットに接続することができます。この手法の詳細はこちらhttp://doc.qt.io/qt-5/qtwebkit-bridge.html

関連する問題