【pywebview】JavaScriptからPythonを実行する

【pywebview】JavaScriptからPythonを実行する プログラミング

「PythonのGUIアプリからWebページにアクセスしたい」
「JavaScriptからPythonを実行したい」
「pywebviewの使い方を知りたい」

本記事の内容

  • 【サンプルコード】JavaScriptからPythonの実行
  • Pythonにおけるコード(呼ばれる側)
  • JavaScriptにおけるコード(呼ぶ側)
  • コードの補足説明

それでは、上記に沿って解説していきます。

【サンプルコード】JavaScriptからPythonの実行

早速ですが、JavaScriptからPythonの実行を試してみましょう。
利用するコードは、以下。

import sys
import webview


class Api:
    def __init__(self):
        self.name = "js_api"

    def my_exec(self):
        response = {
            'message': 'Pythonバージョン: {0}'.format(sys.version)
        }
        return response


def get_html():
    html_str = """
    
    <!DOCTYPE html>
    <html>
    <head lang="en">
    <meta charset="UTF-8">
    
    <style>
        #response-container {
            display: none;
            padding: 3rem;
            margin: 2rem 2rem;
            font-size: 100%;
            border: 2px dashed #ccc;
        }
    
        label {
            margin-left: 0.3rem;
            margin-right: 0.3rem;
        }
    
        button {
          display: inline-block;
          text-decoration: none;
          color: #FFF;
          width: 140px;
          height: 80px;
          font-weight:bold;
          line-height: 80px;
          border-radius: 50%;
          text-align: center;
          overflow: hidden;
          background-image: linear-gradient(45deg, #709dff 0%, #91fdb7 100%);
          transition: .4s;
        }
        
        button:hover {
          -webkit-transform: rotate(10deg);
          transform: rotate(10deg);
        }
                    
    </style>
    </head>
    <body>
    
    <h1>Javascript API</h1>
    <p id='pywebview-status'><i>pywebview</i> is not ready</p>
    <button onClick="exec_python()">Python実行</button><br/>
    
    <div id="response-container"></div>
    <script>
        window.addEventListener('pywebviewready', function() {
            var container = document.getElementById('pywebview-status')
            container.innerHTML = '<i>pywebview</i> is ready'
        })
    
        function get_return_from_python(response) {
            var container = document.getElementById('response-container')
            container.innerText = response.message
            container.style.display = 'block'
        }
    
        function exec_python() {
            pywebview.api.my_exec().then(get_return_from_python)
        }
    
    </script>
    </body>
    </html>
    """
    return html_str


if __name__ == '__main__':
    # GUI
    html = get_html()
    # 関数
    api = Api()
    window = webview.create_window('JavaScriptからPythonを実行する', html=html, js_api=api, height=400)
    webview.start()

上記を実行した結果、次の画面が表示されます。

ボタンは、頑張ってオシャレにしています。
デスクトップアプリでこのようなボタンは、なかなかお目にかかれません。

デスクトップアプリだと、ほぼ100%の確率で四角のボタンです。
画像を使えば、丸いボタンもなんとか可能でしょう。

しかし、pywebviewを使えばcssだけで丸いボタンが実現できます。
では、このオシャレなボタンを押してみましょう。

オンマウスの状態で、ボタンが斜めになります。
こういう微妙なこともcssだけで実現できてしまいます。

ボタンをクリックすると、上記のようにPythonのバージョンが表示されるはずです。
もちろん、Pythonのバージョンは実行環境によって異なります。

ここまでにより、処理的には理解できたはずです。
次は、コードの説明を行います。

説明は、大きく次の2つに分けます。

  • Pythonにおけるコード(呼ばれる側)
  • JavaScriptにおけるコード(呼ぶ側)

以上、JavaScriptからPythonの実行を説明しました。
次は、Pythonにおけるコードを確認します。

Pythonにおけるコード(呼ばれる側)

Pythonにおけるコードとは、JavaScriptから呼ばれる関数です。
正確には、関数を含むクラスとなります。

そのクラスが、サンプルコードでは次の箇所です。

class Api:
    def __init__(self):
        self.name = "js_api"

    def my_exec(self):
        response = {
            'message': 'Pythonバージョン: {0}'.format(sys.version)
        }
        return response

my_exec関数が、JavaScriptからコールされる関数です。
my_exec関数では、辞書型のデータを戻しています。
辞書型であれば、JavaScript上ではObjectとして扱うことができます。

今回は、関数を一つしか設定していません。
もちろん、Apiクラスに複数の関数を設定することは可能です。

以上、Pythonにおけるコードを説明しました。
次は、JavaScriptにおけるコードを確認します。

JavaScriptにおけるコード(呼ぶ側)

まずは、pywebviewで作成されたプログラムから読み込まれているかどうかの確認です。
その判断が、次の部分で行われています。

window.addEventListener('pywebviewready', function() {
    var container = document.getElementById('pywebview-status')
    container.innerHTML = '<i>pywebview</i> is ready'
})

pywebviewと連携が可能であれば、次のように画面上に表示しています。

この状態であれば、次のコードが機能します。
exec_python()は、ボタンのクリックイベントに関連付けています。

function exec_python() {
    pywebview.api.my_exec().then(get_return_from_python)
}

「my_exec()」は、Python上のApiクラスで宣言した関数です。
このような形でJavaScriptからPythonの関数を呼び出します。

そして、呼び出した後の戻り値はget_return_from_python関数で処理しています。
基本的には、次の形を覚えておけばよいでしょう。

pywebview.api.【Python関数】.then(【JavaScript関数】)

戻り値の取得方法は、ajaxのコールバック関数と同じですね。

function get_return_from_python(response) {
    var container = document.getElementById('response-container')
    container.innerText = response.message
    container.style.display = 'block'
}

以上、JavaScriptにおけるコードを説明しました。
最後は、コードの補足説明となります。

コードの補足説明

ここまでは、次の説明を行いました。

  • Pythonにおけるコード(呼ばれる側)
  • JavaScriptにおけるコード(呼ぶ側)

呼ぶ側、呼ばれる側を結合しているのは、次のコードになります。

window = webview.create_window('JavaScriptからPythonを実行する', html=html, js_api=api, height=400)

念のため、補足として説明しました。

タイトルとURLをコピーしました