javascripthtmlpython-3.xflaskpywebview

how to close pywebview window from javascript using pywebview api


I was building an application in pywebview with html and flask i decided to make use of fullscreen mode and make custom nice looking buttons for minimize and exit i.e(window.open('','_self').close();) . The normal javascript code that we use for exit or minimizing winndow in firefox didn't work after some research I got this https://pywebview.flowrl.com/examples/js_api.html but I don't know how to make use of this api to to exit application if someone can write it and explain it to because I didn't understood it if just someone would post the code

here is my application code

from flask import Flask
from flask import render_template, jsonify, request
import webview
import sys
import threading
import http.server
import socketserver
from os import system
system("title Fire - By mzw")
state=1
app=Flask(__name__)
app.config["CACHE_TYPE"] = "null"
@app.route('/')
def home():
    return render_template('start.html', name="Fire")
def start_server():
    cli = sys.modules['flask.cli']
    cli.show_server_banner = lambda *x: None
    app.run(host='0.0.0.0',port=5000)
def start_scanner():
    PORT = 5050
    Handler = http.server.SimpleHTTPRequestHandler
    with socketserver.TCPServer(("", PORT), Handler) as httpd:
        httpd.serve_forever()
if __name__=='__main__':
    t=threading.Thread(target=start_server)
    t.daemon=True
    t.start()
    b=threading.Thread(target=start_scanner)
    b.daemon=True
    b.start()
    webview.create_window("Fire","http://localhost:5000/",fullscreen=True)
    webview.start()
    sys.exit()

here is my html code

<body>
    <nav class="navbar navbar-expand-lg navbar-light bg-amber">
        <a class="navbar-brand" href="#">{{name}}</a>
        <button class="navbar-toggler bg-amber" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon bg-amber"></span>
        </button>
        <div class="collapse navbar-collapse bg-amber" id="navbarNavAltMarkup">
            <div class="navbar-nav bg-amber">
                <a class="nav-item nav-link active" href="#">Home</a>
                <a class="nav-item nav-link" href="#">Features</a>
                <a class="nav-item nav-link" href="#">Pricing</a>
                <a class="nav-item nav-link disabled" href="#">Disabled</a>
            </div>
        </div>
        <div class="float-right bg-amber">
            <a href="#"><img style="width: 30px;height: 30px;" src="{{ url_for('static', filename='green.png') }}"></a>
            <a href="#" id="minimize"><img style="width: 30px;height: 30px;" src="{{ url_for('static', filename='blue.png') }}"></a>
            <a href="#"><img style="width: 30px;height: 30px;" src="{{ url_for('static', filename='red.png') }}"></a>
        </div>
        <script type="text/javascript">
            $("#minimize").click(function(){
                 window.open('','_self').close();
            });
        </script>
    </nav>
</body>

Solution

  • You just need to add a class called Api in your Python code, like it is explained in the article you linked. In your case, that class only needs to include the constructor and a method like this:

    def quit(self):
        self._window.destroy()
    

    (and any other methods you need to execute from python), and then invoke it from javascript with pywebview.api.quit().

    UPDATE: Forgot to mention an important detail. When you create your window, store it in a variable, like so:

      api = Api()
    
      window = webview.create_window(
        ...
        js_api=api,
        ...
      )
      api.set_window(window)
    

    So your Api class would look something like this:

    class Api:
    
      def __init__(self):
        self._window = None
    
      def set_window(self, window):
        self._window = window
    
      def quit(self):
        self._window.destroy()