├── .gitignore ├── README.md ├── build-linux.spec ├── build-macos.py ├── build-windows.spec ├── package.json ├── requirements.txt └── src ├── App.vue ├── index.html ├── index.js └── index.py /.gitignore: -------------------------------------------------------------------------------- 1 | venv-pywebview 2 | gui 3 | .cache 4 | node_modules 5 | package-lock.json 6 | .idea 7 | .vscode -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pywebview-vue-boilerplate 2 | #### based on pywebview-react-boilerplate 3 | This is a simple boilerplate to help you start with _pywebview_ and React. It sets up the development environment, install dependencies, as well as provides scripts for building an executable. Stack is based on pywebview, React, SASS, Parcel bundler, pyinstaller (Windows/Linux) and py2app (macOS). 4 | 5 | ## Requirements 6 | - Python 3 7 | - Node 8 | - virtualenv 9 | 10 | ## Installation 11 | 12 | ``` bash 13 | npm run init 14 | ``` 15 | 16 | This will create a virtual environment, install pip and Node dependencies. Alternatively you can perform these steps manually. 17 | 18 | ``` bash 19 | npm install 20 | pip install -r requirements.txt 21 | ``` 22 | 23 | On Linux systems installation system makes educated guesses. If you run KDE, QT dependencies are installed, otherwise GTK is chosen. `apt` is used for installing GTK dependencies. In case you are running a non apt-based system, you will have to install GTK dependencies manually. See [installation](https://pywebview.flowrl.com/guide/installation.html) for details. 24 | 25 | ## Usage 26 | 27 | To launch the application. 28 | 29 | ``` bash 30 | npm run start 31 | ``` 32 | 33 | To build an executable. The output binary will be produced in the `dist` directory. 34 | 35 | ``` bash 36 | npm run build 37 | ``` 38 | 39 | To start a development server (only for testing frontend code). 40 | 41 | ``` bash 42 | npm run dev 43 | ``` 44 | 45 | 46 | ## Bug reporting 47 | 48 | Please report _pywebview_ related bugs directly to [pywebview's repository](https://github.com/r0x0r/pywebview). This repository is only for the issues related to this boilerplate. 49 | -------------------------------------------------------------------------------- /build-linux.spec: -------------------------------------------------------------------------------- 1 | # -*- mode: python -*- 2 | 3 | block_cipher = None 4 | 5 | added_files = [ 6 | ('./gui', 'gui'), 7 | ] 8 | 9 | a = Analysis(['./src/index.py'], 10 | pathex=['./dist'], 11 | binaries=None, 12 | datas=added_files, 13 | hiddenimports=['clr'], 14 | excludes=[], 15 | win_no_prefer_redirects=False, 16 | win_private_assemblies=False, 17 | cipher=block_cipher) 18 | pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) 19 | exe = EXE(pyz, 20 | a.scripts, 21 | exclude_binaries=True, 22 | name='pywebview-react-app', 23 | debug=False, 24 | strip=True, 25 | #icon='./src/assets/\logo.ico', 26 | upx=True, 27 | console=False ) # set this to see error output of the executable 28 | coll = COLLECT(exe, 29 | a.binaries, 30 | a.zipfiles, 31 | a.datas, 32 | strip=False, 33 | upx=False, 34 | name='pywebview-react-app') 35 | -------------------------------------------------------------------------------- /build-macos.py: -------------------------------------------------------------------------------- 1 | import os 2 | import py2app 3 | import shutil 4 | 5 | from distutils.core import setup 6 | 7 | def tree(src): 8 | return [(root, map(lambda f: os.path.join(root, f), files)) 9 | for (root, dirs, files) in os.walk(os.path.normpath(src))] 10 | 11 | 12 | if os.path.exists('build'): 13 | shutil.rmtree('build') 14 | 15 | if os.path.exists('dist/index.app'): 16 | shutil.rmtree('dist/index.app') 17 | 18 | ENTRY_POINT = ['src/index.py'] 19 | 20 | DATA_FILES = tree('dist') 21 | OPTIONS = { 22 | 'argv_emulation': False, 23 | 'strip': True, 24 | 'iconfile': 'src/assets/logo.icns', 25 | 'includes': ['WebKit', 'Foundation', 'webview', 'pkg_resources.py2_warn'] 26 | } 27 | 28 | setup( 29 | app=ENTRY_POINT, 30 | data_files=DATA_FILES, 31 | options={'py2app': OPTIONS}, 32 | setup_requires=['py2app'], 33 | ) 34 | -------------------------------------------------------------------------------- /build-windows.spec: -------------------------------------------------------------------------------- 1 | # -*- mode: python -*- 2 | 3 | block_cipher = None 4 | 5 | added_files = [ 6 | ('.\\gui', 'gui'), 7 | ] 8 | 9 | a = Analysis(['.\\src\\index.py'], 10 | pathex=['.\\dist'], 11 | binaries=None, 12 | datas=added_files, 13 | hiddenimports=['clr'], 14 | excludes=[], 15 | win_no_prefer_redirects=False, 16 | win_private_assemblies=False, 17 | cipher=block_cipher) 18 | pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher) 19 | exe = EXE(pyz, 20 | a.scripts, 21 | exclude_binaries=True, 22 | name='pywebview-react-app', 23 | debug=False, 24 | strip=True, 25 | icon='.\\src\\assets\\logo.ico', 26 | upx=True, 27 | console=False ) # set this to see error output of the executable 28 | coll = COLLECT(exe, 29 | a.binaries, 30 | a.zipfiles, 31 | a.datas, 32 | strip=False, 33 | upx=False, 34 | name='pywebview-react-app') 35 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pywebview_vue", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "frontend:dev": "parcel build src/index.html --public-url . -d gui", 8 | "clean": "run-script-os", 9 | "clean:default": "rm -rf dist 2>/dev/null; rm -rf gui 2>/dev/null; rm -rf build 2>/dev/null; ", 10 | "clean:windows": "if exist dist rd /S /Q dist & if exist build rd /S /Q build & if exist gui rd /S /Q gui", 11 | "dev": "parcel serve src/index.html", 12 | "init": "npm install && run-script-os", 13 | "init:linux": "virtualenv -p python3 venv-pywebview && if [[ -z \\\"${KDE_FULL_SESSION}\\\" ]]; then npm run init:qt5; else npm run init:gtk; fi", 14 | "init:gtk": "sudo apt install libgirepository1.0-dev gcc libcairo2-dev pkg-config python3-dev gir1.2-gtk-3.0 && ./venv-pywebview/bin/pip install pycairo pygobject -r requirements.txt", 15 | "start": "npm run frontend:dev && run-script-os", 16 | "start:default": "./venv-pywebview/bin/python src/index.py", 17 | "start:windows": ".\\venv-pywebview\\Scripts\\python src\\index.py" 18 | }, 19 | "keywords": [], 20 | "author": "", 21 | "license": "ISC", 22 | "dependencies": { 23 | "vue": "^2.6.12", 24 | "vue-template-compiler": "^2.6.12" 25 | }, 26 | "devDependencies": { 27 | "@vue/component-compiler-utils": "^3.2.0", 28 | "parcel-bundler": "^1.12.5", 29 | "run-script-os": "^1.1.6" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | setuptools 2 | pywebview 3 | pyinstaller; sys_platform != 'darwin' 4 | py2app; sys_platform == 'darwin' -------------------------------------------------------------------------------- /src/App.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 22 | 23 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | Document 9 | 10 | 11 |
12 | 13 | 14 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | import App from './App.vue'; 3 | 4 | new Vue({render: createElement => createElement(App)}).$mount('#app'); -------------------------------------------------------------------------------- /src/index.py: -------------------------------------------------------------------------------- 1 | import os 2 | import threading 3 | import webview 4 | 5 | from time import time 6 | 7 | 8 | class Api: 9 | def fullscreen(self): 10 | webview.windows[0].toggle_fullscreen() 11 | 12 | def save_content(self, content): 13 | filename = webview.windows[0].create_file_dialog(webview.SAVE_DIALOG) 14 | if not filename: 15 | return 16 | 17 | with open(filename, 'w') as f: 18 | f.write(content) 19 | 20 | def ls(self): 21 | return os.listdir('.') 22 | 23 | def takeScreenshot(self): 24 | print('Take screenshot 5') 25 | return 26 | 27 | 28 | def get_entrypoint(): 29 | def exists(path): 30 | return os.path.exists(os.path.join(os.path.dirname(__file__), path)) 31 | 32 | if exists('../gui/index.html'): # unfrozen development 33 | return '../gui/index.html' 34 | 35 | if exists('../Resources/gui/index.html'): # frozen py2app 36 | return '../Resources/gui/index.html' 37 | 38 | if exists('./gui/index.html'): 39 | return './gui/index.html' 40 | 41 | raise Exception('No index.html found') 42 | 43 | 44 | entry = get_entrypoint() 45 | 46 | if __name__ == '__main__': 47 | api = Api() 48 | window = webview.create_window('pywebview-vue boilerplate', entry, js_api=api) 49 | webview.start(debug=True) 50 | --------------------------------------------------------------------------------