๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Python/pywebview

[Python] pywebview - webview ๋งŒ๋“ค๊ธฐ

๋ฐ˜์‘ํ˜•

 

์„ค์น˜

pip install pywebview

 

Hello world:

import webview
webview.create_window('Hello world', 'https://pywebview.flowrl.com/')
webview.start()

 

 

HTML ๋ถˆ๋Ÿฌ์˜ค๊ธฐ

url, html ๋‘˜ ๋‹ค ์žˆ์„ ๊ฒฝ์šฐ html ์ด ์šฐ์„  ์ˆœ์œ„๋ฅผ ๊ฐ€์ง„๋‹ค.

import webview

webview.create_window('Woah dude!', html='<h1>Woah dude!<h1>')
webview.start()

 

 

HTML ํŒŒ์ผ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ

import webview

webview.create_window('Woah dude!', 'index.html')
webview.start()

 

HTTP server

pywebview๋Š” WSGI ํ˜ธํ™˜ HTTP ์„œ๋ฒ„๋ฅผ ์ œ๊ณตํ•œ๋‹ค. HTTP ์„œ๋ฒ„๋ฅผ ์‹œ์ž‘ํ•˜๋ ค๋ฉด url์„ ํ”„๋กœํ† ์ฝœ ์Šคํ‚ค๋งˆ ์—†์ด ๋กœ์ปฌ ์ง„์ž…์ ์œผ๋กœ ์„ค์ •ํ•˜๊ณ  start ํ•จ์ˆ˜์˜ http_server ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ True๋กœ ์„ค์ •ํ•œ๋‹ค.

import webview

webview.create_window('Woah dude!', 'index.html')
webview.start(http_server=True)

 

pywebview์™€ ํ•จ๊ป˜ ์™ธ๋ถ€ WSGI ํ˜ธํ™˜ HTTP ์„œ๋ฒ„๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์„œ๋ฒ„ ๊ฐ์ฒด๋ฅผ URL๋กœ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ๊ฒฝ์šฐ http_server ๋งค๊ฐœ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•  ํ•„์š”๊ฐ€ ์—†๋‹ค.

from flask import Flask
import webview

server = Flask(__name__, static_folder='./assets', template_folder='./templates')
webview.create_window('Flask example', server)
webview.start()

 

Threading model

 

 

import webview

def custom_logic(window):
    window.toggle_fullscreen()
    window.evaluate_js('alert("Nice one brother")')

window = webview.create_window('Woah dude!', html='<h1>Woah dude!<h1>')
webview.start(custom_logic, window)
# anything below this line will be executed after program is finished executing
pass

 

 

https://pywebview.flowrl.com/guide/usage.html#basics

 

Usage | pywebview

Usage Basics The bare minimum to get pywebview up and running is The create_window function returns a window instance that provides a number of both window manipulation and DOM related functions. You may create as many windows as you wish. Windows created

pywebview.flowrl.com

 

 

https://codingdiary26.tistory.com/20

 

[Python] Pywebview๋ฅผ ์ด์šฉํ•œ ์›น๋ทฐ์•ฑ ๋งŒ๋“ค๊ธฐ! - 1

์˜ค๋Š˜์€ Python์—์„œ ๊ฐ„๋‹จํ•˜๊ฒŒ ์›น๋ทฐ๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋Š” pywebview๋ผ๋Š” ๋ชจ๋“ˆ์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค :) (์ด๋ฒˆ ๊ธ€์€ pywebview์— ๋Œ€ํ•œ ์•„์ฃผ ์•„์ฃผ ์•„์ฃผ ์•„์ฃผ ๊ฐ„๋‹จํ•œ ์˜ˆ์ œ์™€ ์„ค๋ช…์ž…๋‹ˆ๋‹ค!) ์šฐ์„ , ์ด pywebview๋Š” ์•„์ฃผ

codingdiary26.tistory.com

 

 

Application architecture

https://pywebview.flowrl.com/guide/architecture.html#local-web-server

 

pywebview๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋นŒ๋“œํ•˜๋Š” ๋‘ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.

  1. ๋กœ์ปฌ ์›น ์„œ๋ฒ„ ์‹คํ–‰
  2. ์„œ๋ฒ„๋ฆฌ์Šค (JS API or window.expose) and ๋กœ์ปฌ ํŒŒ์ผ ์ด์šฉ

Local web server

Flask ๊ธฐ๋ฐ˜ ์˜ˆ์ œ

 

index.html

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <style type="text/css">
        body {
            color: #333;
            font-size: 14pt;
        }

        h1 {
            font-size: 24pt;
        }

    </style>
</head>
<body>

<h1>My first pywebview application</h1>

<button onclick="openFolder()">Open folder</button>
<button onclick="toggleFullscreen()">Toggle fullscreen</button>
<button onclick="doStuff()">Do stuff</button>
<div id="open-folder-container"></div>
<div id="stuff-container"></div>
<div id="json-container"></div>

<div style="text-align: center; margin-top: 50px;">
    <a href="http://mbsy.co/gHVfC" target="_blank" style="outline:none;border:none;" onclick="openLink(event)">
        <img src="https://ambassador-api.s3.amazonaws.com/uploads/marketing/11948/2016_11_29_21_53_43.png" alt="DreamHost" border="0" />
    </a>
</div>

<script>
    window.token = '{{ token }}';
    // Perform background initialization
    doAjax("/init", "POST");

    function getMethods(obj) {
      var result = [];
      for (var id in obj) {
        try {
          if (typeof(obj[id]) == "function") {
            result.push(id + ": " + obj[id].toString());
          }
        } catch (err) {
          result.push(id + ": inaccessible");
        }
      }
      return result;
}

    function openFolderHandler() {
        if (this.responseText) {
            var response = JSON.parse(this.responseText);
            document.getElementById("open-folder-container").innerHTML = 'Selected directory: ' + response.directory;
        }
    }

    function doStuffHandler(response) {
        if (this.responseText) {
            var response = JSON.parse(this.responseText);
            document.getElementById("stuff-container").innerHTML = response.result;
        }

    }

    function openFolder() {
        doAjax("/choose/path", "POST", openFolderHandler);
    }

    function doStuff() {
        doAjax("/do/stuff", "POST", doStuffHandler);
    }

    function toggleFullscreen() {
        doAjax("/fullscreen", "POST", doStuffHandler);
    }

    function openLink(e) {
        e.preventDefault()
        var request = {url: e.currentTarget.href}
        doAjax("/open-url", "POST", false, request)
    }

    // From https://gist.github.com/dharmavir/936328
    function getHttpRequestObject()
    {
        // Define and initialize as false
        var xmlHttpRequst = false;

        // Mozilla/Safari/Non-IE
        if (window.XMLHttpRequest)
        {
            xmlHttpRequst = new XMLHttpRequest();
        }
        // IE
        else if (window.ActiveXObject)
        {
            xmlHttpRequst = new ActiveXObject("Microsoft.XMLHTTP");
        }
        return xmlHttpRequst;
    }

    // Does the AJAX call to URL specific with rest of the parameters
    function doAjax(url, method, responseHandler, data)
    {
        // Set the variables
        url = url || "";
        method = method || "GET";
        async = true;
        data = data || {};
        data.token = window.token;

        if(url == "") {
            alert("URL can not be null/blank");
            return false;
        }
        var xmlHttpRequest = getHttpRequestObject();

        // If AJAX supported
        if(xmlHttpRequest != false) {
            xmlHttpRequest.open(method, url, async);
            // Set request header (optional if GET method is used)
            if(method == "POST")  {
                xmlHttpRequest.setRequestHeader("Content-Type", "application/json");
            }
            // Assign (or define) response-handler/callback when ReadyState is changed.
            xmlHttpRequest.onreadystatechange = responseHandler;
            // Send data
            xmlHttpRequest.send(JSON.stringify(data));
        }
        else
        {
            alert("Please use browser with Ajax support.!");
        }
    }
</script>
</body>
</html>

 

 

 

 

 

Serverless

์„œ๋ฒ„๋ฆฌ์Šค ์•ฑ ์˜ˆ์ œ

start.py

import os
import webview

"""
An example of serverless app architecture
"""


class Api():
    def addItem(self, title):
        print('Added item %s' % title)

    def removeItem(self, item):
        print('Removed item %s' % item)

    def editItem(self, item):
        print('Edited item %s' % item)

    def toggleItem(self, item):
        print('Toggled item %s' % item)

    def toggleFullscreen(self):
        webview.windows[0].toggle_fullscreen()


if __name__ == '__main__':
    api = Api()
    webview.create_window('Todos magnificos', 'assets/index.html', js_api=api, min_size=(600, 450))
    webview.start()

 

setup.py

from distutils.core import setup

import sys
import os
import shutil


def tree(src):
    return [(root, map(lambda f: os.path.join(root, f), filter(lambda f: os.path.splitext(f)[1] != ".map", files))) for (root, dirs, files) in os.walk(os.path.normpath(src))]


APP = ['start.py']
DATA_FILES = tree('assets')
OPTIONS_OSX = {'argv_emulation': False,
               'strip': True,
               'includes': ['WebKit', 'Foundation', 'webview']}

if os.path.exists('build'):
    shutil.rmtree('build')

if os.path.exists('dist'):
    shutil.rmtree('dist')

if sys.platform == 'darwin':
    import py2app

    setup(
        app=APP,
        data_files=DATA_FILES,
        options={'py2app': OPTIONS_OSX},
        setup_requires=['py2app'],
    )

 

https://github.com/r0x0r/pywebview/tree/master/examples/todos

 

GitHub - r0x0r/pywebview: Build GUI for your Python program with JavaScript, HTML, and CSS

Build GUI for your Python program with JavaScript, HTML, and CSS - GitHub - r0x0r/pywebview: Build GUI for your Python program with JavaScript, HTML, and CSS

github.com

 

 

 

 

 

 

 

https://pywebview.flowrl.com/guide/architecture.html#local-web-server

 

Application architecture | pywebview

Application architecture There are two ways to build your application using pywebview: By running a local web server Serverless with pywebview's JS API or window.expose and serving local files. Local web server Running a local web server is a traditional w

pywebview.flowrl.com

 

 

 

 

 

 

 

 

 

 

 

 

๋ฐ˜์‘ํ˜•