2017-07-27 22 views
0

私はPythonでhtml + jsコードを作成し、それをQWebViewにロードするアプリケーションを構築しようとしています。QWebViewでpython変数としてjs console.logを取得するpyqt

最終html + jsコードは、次の(here利用できる生コード)である:

<head><meta charset="utf-8" /><script src="https://cdn.plot.ly/plotly-latest.min.js"></script></head><div id="myDiv" style="height: 100%; width: 100%;" class="plotly-graph-div"></div><script type="text/javascript">window.PLOTLYENV=window.PLOTLYENV || {};window.PLOTLYENV.BASE_URL="https://plot.ly";Plotly.newPlot("myDiv", [{"type": "scatter", "x": [6.81, 6.78, 6.49, 6.72, 6.88, 7.68, 7.69, 7.38, 6.76, 6.84, 6.91, 6.74, 6.77, 6.73, 6.68, 6.94, 6.72], "y": [1046.67, 1315.0, 1418.0, 997.33, 2972.3, 9700.0, 6726.0, 6002.5, 2096.0, 2470.0, 867.0, 2201.7, 1685.6, 2416.7, 1618.3, 2410.0, 2962.0], "mode": "markers", "ids": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]}], {"showlegend": true}, {"linkText": "Export to plot.ly", "showLink": false})</script> 
<script>  
    var plotly_div = document.getElementById('myDiv') 
    var plotly_data = plotly_div.data 
    plotly_div.on('plotly_selected', function(data){ 
    featureId = plotly_data[0].ids[data.points[0].pointNumber] 
    featureIds = [] 
    data.points.forEach(function(pt) { 
    featureIds.push(parseInt(pt.id)) 
     }) 
    console.log(featureIds) 
    }) 
</script> 

このコードはplotly PythonのAPIのおかげで、プロットを作成します。ローカルファイル(例えば/home/matteo/plot.html)のプロットを保存することで、私は次のコードでQWebViewにそれをロードすることができるよ:

from PyQt5.QtWebKit import QWebSettings 
from PyQt5.QtWebKitWidgets import * 
from PyQt5.QtCore import QUrl 
import json 

plot_view = QWebView() 
plot_view.page().setNetworkAccessManager(QgsNetworkAccessManager.instance()) 
plot_view_settings = plot_view.settings() 
plot_view_settings.setAttribute(QWebSettings.WebGLEnabled, True) 
plot_view_settings.setAttribute(QWebSettings.DeveloperExtrasEnabled, True) 
plot_view_settings.setAttribute(QWebSettings.Accelerated2dCanvasEnabled, True) 

plot_path = '/home/matteo/plot.html' 
plot_url = QUrl.fromLocalFile(plot_path) 
plot_view.load(plot_url) 
plot_view.show() 

上記のjavascript関数は、単にの選択された点のIDを返しますプロットのlasso selectionツールを使用しているときにjavascriptコンソールのプロット。

inspectツールでチェックすると、それはQWebViewでもうまくいきます:選択肢の中にある要素がconsole.logにあるたびに、対応するidのIDを見ることができます。

これはjsfiddle(投げ縄選択、点選択とにconsole.log出力)から採取された静​​止画像である:

enter image description here

実行中のコードは単なるデバッグコンソールを有効にして、いくつかの点を選択し、here利用可能です金具選択ツールを使用してください。

私が実際に達成したいのは、コンソールの出力を(選択されたポイントのIDのように)取り出し、それらをアプリケーションに再注入して、使用可能なPythonオブジェクト(リスト、辞書、何でも)私が選択するたびに。

Pythonオブジェクトを取得するために、QWebPageのJavaScriptコンソールをリンクする方法はありますか?

答えて

1

console.log()出力を取得するには、メソッドjavaScriptConsoleMessage()を上書きするだけで済みます。

プラス:ポイントのリストにアクセスする2つの方法が追加されました。最初は属性objを使用し、2番目の方法は信号を使用しています。

class _LoggedPage(QWebPage): 
    obj = [] # synchronous 
    newData = pyqtSignal(list) #asynchronous 
    def javaScriptConsoleMessage(self, msg, line, source): 
     l = msg.split(",") 
     self.obj = l 
     self.newData.emit(l) 
     print ('JS: %s line %d: %s' % (source, line, msg)) 

完全な例:答えを

class _LoggedPage(QWebPage): 
    obj = [] # synchronous 
    newData = pyqtSignal(list) #asynchronous 
    def javaScriptConsoleMessage(self, msg, line, source): 
     l = msg.split(",") 
     self.obj = l 
     self.newData.emit(l) 
     print ('JS: %s line %d: %s' % (source, line, msg)) 

def onNewData(data): 
    print("asynchronous", data) 

app = QApplication(sys.argv) 
plot_view = QWebView() 
page = _LoggedPage() 
page.newData.connect(onNewData) 

plot_view.setPage(page) 
plot_path = '/home/qhipa/plot.html' 
plot_url = QUrl.fromLocalFile(plot_path) 
plot_view.load(plot_url) 
plot_view_settings = plot_view.settings() 
plot_view_settings.setAttribute(QWebSettings.WebGLEnabled, True) 
plot_view_settings.setAttribute(QWebSettings.DeveloperExtrasEnabled, True) 
plot_view_settings.setAttribute(QWebSettings.Accelerated2dCanvasEnabled, True) 

# synchronous request simulation 
timer = QTimer(plot_view) 
timer.timeout.connect(lambda: print("synchronous", page.obj)) 
timer.start(1000) 

plot_view.show() 
sys.exit(app.exec_()) 
+0

感謝します。私はあなたのコードを使用し、それは動作します。しかし、2番目の瞬間に使用できる変数に出力を格納することはできません。 '' javaScriptConsoleMessage''の直前に '' obj = [] ''を追加してコードを編集し、オブジェクト '' retunr self.obj''を返そうとすると、私はいつも同じエラーが出ます: 'TypeError:_LoggedPage .javaScriptConsoleMessage() 'を実行します。何か不足していますか?再度、感謝します! – matteo

+0

完璧!ありがとう! – matteo

関連する問題