mirror of
https://github.com/webui-dev/webui
synced 2025-03-28 21:13:17 +00:00
Python Wrapper (Not Complete)
* First Python Wrapper Commit v2.2.0 (Not Complete) * Adding `windows_build.bat`
This commit is contained in:
parent
2de4a80867
commit
04b3ab7734
3
.gitignore
vendored
3
.gitignore
vendored
@ -2,13 +2,12 @@
|
||||
*.exe
|
||||
*.ilk
|
||||
*.pdb
|
||||
*.lib
|
||||
*.exp
|
||||
*.res
|
||||
*.out
|
||||
*.o
|
||||
*.def
|
||||
*.obj
|
||||
*.o
|
||||
|
||||
# IDE
|
||||
.idea/
|
||||
|
BIN
build/Windows/GCC/libwebui-2-static-x64.a
Normal file
BIN
build/Windows/GCC/libwebui-2-static-x64.a
Normal file
Binary file not shown.
Binary file not shown.
BIN
build/Windows/MSVC/webui-2-static-x64.lib
Normal file
BIN
build/Windows/MSVC/webui-2-static-x64.lib
Normal file
Binary file not shown.
Binary file not shown.
BIN
build/Windows/MSVC/webui-2-x64.lib
Normal file
BIN
build/Windows/MSVC/webui-2-x64.lib
Normal file
Binary file not shown.
BIN
build/Windows/TCC/libwebui-2-static-x64.a
Normal file
BIN
build/Windows/TCC/libwebui-2-static-x64.a
Normal file
Binary file not shown.
BIN
build/Windows/TCC/webui-2-x64.dll
Normal file
BIN
build/Windows/TCC/webui-2-x64.dll
Normal file
Binary file not shown.
110
build/windows_build.bat
Normal file
110
build/windows_build.bat
Normal file
@ -0,0 +1,110 @@
|
||||
@echo off
|
||||
|
||||
set WEBUI_VERSION=2.2.0
|
||||
|
||||
set ARG1=%1
|
||||
IF "%ARG1%"=="debug" (
|
||||
set MSVC_CMD=nmake debug
|
||||
set GCC_CMD=mingw32-make debug
|
||||
) else (
|
||||
set MSVC_CMD=nmake
|
||||
set GCC_CMD=mingw32-make
|
||||
)
|
||||
|
||||
echo.
|
||||
echo WebUI v%WEBUI_VERSION% Build Script
|
||||
echo Platform: Microsoft Windows x64
|
||||
echo Compiler: MSVC and GCC
|
||||
|
||||
Set RootPath=%CD%\..\
|
||||
cd "%RootPath%"
|
||||
|
||||
echo.
|
||||
echo - - [Build MSVC] - - - - - - - - - - - - - -
|
||||
|
||||
REM Build WebUI Library using MSVC
|
||||
cd "%RootPath%"
|
||||
cd "build\Windows\MSVC"
|
||||
%MSVC_CMD%
|
||||
|
||||
echo.
|
||||
echo - - [Build GCC] - - - - - - - - - - - - - -
|
||||
echo.
|
||||
|
||||
REM Build WebUI Library using GCC
|
||||
cd "%RootPath%"
|
||||
cd "build\Windows\GCC"
|
||||
%GCC_CMD%
|
||||
|
||||
echo.
|
||||
echo - - [Build TCC] - - - - - - - - - - - - - -
|
||||
echo.
|
||||
|
||||
REM Build WebUI Library using TCC
|
||||
cd "%RootPath%"
|
||||
cd "build\Windows\TCC"
|
||||
%GCC_CMD%
|
||||
|
||||
echo.
|
||||
echo - - [Copy Libs] - - - - - - - - - - - - - -
|
||||
echo.
|
||||
|
||||
cd "%RootPath%"
|
||||
|
||||
REM Golang
|
||||
copy /Y "include\webui.h" "examples\Go\hello_world\webui\webui.h"
|
||||
copy /Y "build\Windows\GCC\libwebui-2-static-x64.a" "examples\Go\hello_world\webui\libwebui-2-static-x64.a"
|
||||
|
||||
REM Deno
|
||||
copy /Y "build\Windows\MSVC\webui-2-x64.dll" "examples\TypeScript\Deno\webui-2-x64.dll"
|
||||
|
||||
REM Python
|
||||
copy /Y "build\Windows\MSVC\webui-2-x64.dll" "examples\Python\PyPI\Package\src\webui\webui-2-x64.dll"
|
||||
|
||||
echo.
|
||||
IF "%ARG1%"=="" (
|
||||
|
||||
echo - - [Copy Release Libs] - - - - - - - - - -
|
||||
echo.
|
||||
|
||||
REM Release Windows Include
|
||||
copy /Y "include\webui.h" "Release\Windows\include\webui.h"
|
||||
|
||||
REM Release Windows MSVC
|
||||
copy /Y "build\Windows\MSVC\webui-2-x64.dll" "Release\Windows\MSVC\webui-2-x64.dll"
|
||||
copy /Y "build\Windows\MSVC\webui-2-x64.lib" "Release\Windows\MSVC\webui-2-x64.lib"
|
||||
copy /Y "build\Windows\MSVC\webui-2-static-x64.lib" "Release\Windows\MSVC\webui-2-static-x64.lib"
|
||||
|
||||
REM Release Windows GCC
|
||||
copy /Y "build\Windows\GCC\webui-2-x64.dll" "Release\Windows\GCC\webui-2-x64.dll"
|
||||
copy /Y "build\Windows\GCC\libwebui-2-static-x64.a" "Release\Windows\GCC\libwebui-2-static-x64.a"
|
||||
|
||||
REM Release Windows TCC
|
||||
copy /Y "build\Windows\TCC\webui-2-x64.dll" "Release\Windows\TCC\webui-2-x64.dll"
|
||||
copy /Y "build\Windows\TCC\libwebui-2-static-x64.a" "Release\Windows\TCC\libwebui-2-static-x64.a"
|
||||
copy /Y "build\Windows\TCC\webui-2-x64.def" "Release\Windows\TCC\webui-2-x64.def"
|
||||
|
||||
echo.
|
||||
echo - - [Compress Release Folder] - - - - - - - -
|
||||
echo.
|
||||
|
||||
set TAR_OUT=webui-windows-x64-v%WEBUI_VERSION%.zip
|
||||
cd "Release"
|
||||
tar.exe -c -f %TAR_OUT% Windows
|
||||
cd "%RootPath%"
|
||||
|
||||
echo.
|
||||
echo - - [Clean] - - - - - - - - - - - - - - - - -
|
||||
|
||||
DEL /Q /F /S "*.exe" >nul 2>&1
|
||||
DEL /Q /F /S "*.o" >nul 2>&1
|
||||
DEL /Q /F /S "*.exp" >nul 2>&1
|
||||
DEL /Q /F /S "*.pdb" >nul 2>&1
|
||||
DEL /Q /F /S "*.ilk" >nul 2>&1
|
||||
DEL /Q /F /S "*.obj" >nul 2>&1
|
||||
DEL /Q /F /S "*.res" >nul 2>&1
|
||||
DEL /Q /F /S "*.bak" >nul 2>&1
|
||||
DEL /Q /F /S "*.DS_Store" >nul 2>&1
|
||||
)
|
||||
|
||||
cd "build"
|
BIN
examples/Go/hello_world/webui/libwebui-2-static-x64.a
Normal file
BIN
examples/Go/hello_world/webui/libwebui-2-static-x64.a
Normal file
Binary file not shown.
Binary file not shown.
@ -26,46 +26,32 @@ PTR_PTR_CHAR = ctypes.POINTER(PTR_CHAR)
|
||||
|
||||
# Event
|
||||
class event:
|
||||
window_id = 0
|
||||
element_name = ""
|
||||
data = ""
|
||||
window = None
|
||||
c_window = None
|
||||
|
||||
|
||||
# WebUI C-Struct
|
||||
class webui_script_interface_t(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("script", c_char_p),
|
||||
("timeout", c_uint),
|
||||
("error", c_bool),
|
||||
("length", c_uint),
|
||||
("data", c_char_p)
|
||||
]
|
||||
Window = None
|
||||
EventType = 0
|
||||
Element = ""
|
||||
Data = ""
|
||||
|
||||
|
||||
# JavaScript
|
||||
class javascript:
|
||||
script = ""
|
||||
timeout = 10
|
||||
error = False
|
||||
length = 0
|
||||
data = ""
|
||||
Error = False
|
||||
Response = ""
|
||||
|
||||
|
||||
# Scripts Runtime
|
||||
class runtime:
|
||||
none = 0
|
||||
deno = 1
|
||||
nodejs = 2
|
||||
Deno = 1
|
||||
Nodejs = 2
|
||||
|
||||
|
||||
# The window class
|
||||
class window:
|
||||
|
||||
window = None
|
||||
window_id = None
|
||||
c_events = None
|
||||
cb_fun_list = [64]
|
||||
cb_fun_list = {}
|
||||
|
||||
def __init__(self):
|
||||
global WebUI
|
||||
@ -82,16 +68,18 @@ class window:
|
||||
webui_wrapper = WebUI.webui_new_window
|
||||
webui_wrapper.restype = c_void_p
|
||||
self.window = c_void_p(webui_wrapper())
|
||||
# Get the window unique ID
|
||||
self.window_id = int(
|
||||
WebUI.webui_interface_get_window_id(
|
||||
self.window))
|
||||
# Initializing events() to be used by
|
||||
# WebUI library as a callback
|
||||
py_fun = ctypes.CFUNCTYPE(
|
||||
ctypes.c_void_p,
|
||||
ctypes.c_uint,
|
||||
ctypes.c_uint,
|
||||
ctypes.c_char_p,
|
||||
ctypes.c_void_p,
|
||||
ctypes.c_char_p,
|
||||
PTR_PTR_CHAR)
|
||||
ctypes.c_void_p, # Window
|
||||
ctypes.c_uint, # EventType
|
||||
ctypes.c_char_p, # Element
|
||||
ctypes.c_char_p, # Data
|
||||
ctypes.c_char_p) # Response
|
||||
self.c_events = py_fun(self.events)
|
||||
except OSError as e:
|
||||
print(
|
||||
@ -105,26 +93,22 @@ class window:
|
||||
# WebUI.webui_close(self.window)
|
||||
|
||||
|
||||
def events(self, element_id, window_id,
|
||||
element_name, window, data, response):
|
||||
if self.cb_fun_list[int(element_id)] is None:
|
||||
def events(self, window, event_type,
|
||||
element, data, response):
|
||||
if self.cb_fun_list[self.window_id][element] is None:
|
||||
print('WebUI Error: Callback is None.')
|
||||
return
|
||||
# Create event
|
||||
e = event()
|
||||
e.element_id = int(element_id)
|
||||
e.window_id = int(window_id)
|
||||
e.data = data.decode('utf-8')
|
||||
e.element_name = element_name.decode('utf-8')
|
||||
e.window = self
|
||||
e.c_window = window
|
||||
e.Window = self
|
||||
e.EventType = int(event_type)
|
||||
e.Element = element.decode('utf-8')
|
||||
e.Data = data.decode('utf-8')
|
||||
# User callback
|
||||
cb_res = str(self.cb_fun_list[element_id](e))
|
||||
cb_res = str(self.cb_fun_list[self.window_id][element](e))
|
||||
cb_res_encode = cb_res.encode('utf-8')
|
||||
# Allocate a new memory
|
||||
buffer = ctypes.create_string_buffer(cb_res_encode)
|
||||
# Set the response
|
||||
response[0] = buffer
|
||||
WebUI.webui_interface_bind(response, cb_res_encode)
|
||||
|
||||
|
||||
def bind(self, element, func):
|
||||
@ -135,15 +119,16 @@ class window:
|
||||
if WebUI is None:
|
||||
err_library_not_found('bind')
|
||||
return
|
||||
cb_index = int(
|
||||
WebUI.webui_interface_bind(
|
||||
self.window,
|
||||
element.encode('utf-8'),
|
||||
self.c_events))
|
||||
self.cb_fun_list.insert(cb_index, func)
|
||||
# Bind
|
||||
WebUI.webui_interface_bind(
|
||||
self.window,
|
||||
element.encode('utf-8'),
|
||||
self.c_events)
|
||||
# Add CB to the list
|
||||
self.cb_fun_list[self.window_id] = {element: func}
|
||||
|
||||
|
||||
def show(self, html="<html></html>"):
|
||||
def show(self, content="<html></html>"):
|
||||
global WebUI
|
||||
if self.window is None:
|
||||
err_window_is_none('show')
|
||||
@ -151,59 +136,31 @@ class window:
|
||||
if WebUI is None:
|
||||
err_library_not_found('show')
|
||||
return
|
||||
WebUI.webui_show(self.window, html.encode('utf-8'))
|
||||
# Show the window
|
||||
WebUI.webui_show(self.window, content.encode('utf-8'))
|
||||
|
||||
|
||||
def open(self, url, browser=0):
|
||||
def set_runtime(self, rt=runtime.deno):
|
||||
global WebUI
|
||||
if self.window is None:
|
||||
err_window_is_none('open')
|
||||
err_window_is_none('set_runtime')
|
||||
return
|
||||
if WebUI is None:
|
||||
err_library_not_found('open')
|
||||
err_library_not_found('set_runtime')
|
||||
return
|
||||
WebUI.webui_open(self.window,
|
||||
url.encode('utf-8'), ctypes.c_uint(browser))
|
||||
|
||||
|
||||
def script_runtime(self, rt=runtime.deno):
|
||||
global WebUI
|
||||
if self.window is None:
|
||||
err_window_is_none('script_runtime')
|
||||
return
|
||||
if WebUI is None:
|
||||
err_library_not_found('script_runtime')
|
||||
return
|
||||
WebUI.webui_script_runtime(self.window,
|
||||
WebUI.webui_set_runtime(self.window,
|
||||
ctypes.c_uint(rt))
|
||||
|
||||
|
||||
def new_server(self, path=""):
|
||||
def set_multi_access(self, status=False):
|
||||
global WebUI
|
||||
if self.window is None:
|
||||
err_window_is_none('new_server')
|
||||
err_window_is_none('set_multi_access')
|
||||
return
|
||||
if WebUI is None:
|
||||
err_library_not_found('new_server')
|
||||
err_library_not_found('set_multi_access')
|
||||
return
|
||||
webui_wrapper = None
|
||||
webui_wrapper = WebUI.webui_new_server
|
||||
webui_wrapper.argtypes = [c_void_p, c_void_p]
|
||||
webui_wrapper.restype = c_char_p
|
||||
url = c_char_p(webui_wrapper(self.window,
|
||||
path.encode('utf-8'))).value.decode('utf-8')
|
||||
return url
|
||||
|
||||
|
||||
def multi_access(self, status=False):
|
||||
global WebUI
|
||||
if self.window is None:
|
||||
err_window_is_none('multi_access')
|
||||
return
|
||||
if WebUI is None:
|
||||
err_library_not_found('multi_access')
|
||||
return
|
||||
WebUI.webui_multi_access(self.window,
|
||||
WebUI.webui_set_multi_access(self.window,
|
||||
ctypes.c_bool(status))
|
||||
|
||||
|
||||
@ -215,23 +172,15 @@ class window:
|
||||
WebUI.webui_close(self.window)
|
||||
|
||||
|
||||
def is_any_window_running(self):
|
||||
global WebUI
|
||||
if WebUI is None:
|
||||
err_library_not_found('close')
|
||||
return
|
||||
r = bool(WebUI.webui_is_any_window_running())
|
||||
return r
|
||||
|
||||
def is_shown(self):
|
||||
global WebUI
|
||||
if WebUI is None:
|
||||
err_library_not_found('close')
|
||||
err_library_not_found('is_shown')
|
||||
return
|
||||
r = bool(WebUI.webui_is_shown(self.window))
|
||||
return r
|
||||
|
||||
def run_js(self, script, timeout=0) -> javascript:
|
||||
def script(self, script, timeout=0, response_size=(1024 * 8)) -> javascript:
|
||||
global WebUI
|
||||
if self.window is None:
|
||||
err_window_is_none('show')
|
||||
@ -239,27 +188,20 @@ class window:
|
||||
if WebUI is None:
|
||||
err_library_not_found('show')
|
||||
return
|
||||
# Create Struct
|
||||
js = webui_script_interface_t()
|
||||
# Initializing
|
||||
js.script = ctypes.c_char_p(script.encode('utf-8'))
|
||||
js.timeout = ctypes.c_uint(timeout)
|
||||
js.error = ctypes.c_bool(False)
|
||||
js.length = ctypes.c_uint(0)
|
||||
js.data = ctypes.c_char_p("".encode('utf-8'))
|
||||
# Create Buffer
|
||||
buffer = ctypes.create_string_buffer(response_size)
|
||||
buffer.value = b""
|
||||
# Create a pointer to the buffer
|
||||
buffer_ptr = ctypes.pointer(buffer)
|
||||
# Run JavaScript
|
||||
status = bool(WebUI.webui_script(self.window,
|
||||
ctypes.c_char_p(script.encode('utf-8')),
|
||||
ctypes.c_uint(timeout), buffer_ptr,
|
||||
ctypes.c_uint(response_size)))
|
||||
# Initializing Result
|
||||
res = javascript()
|
||||
res.script = script
|
||||
res.timeout = timeout
|
||||
res.error = True
|
||||
res.length = 7
|
||||
res.data = "UNKNOWN"
|
||||
# Run JavaScript
|
||||
WebUI.webui_script_interface_struct(self.window,
|
||||
ctypes.byref(js))
|
||||
res.length = int(js.length)
|
||||
res.data = js.data.decode('utf-8')
|
||||
res.error = js.error
|
||||
res.data = buffer.value.decode('utf-8')
|
||||
res.error = status
|
||||
return res
|
||||
|
||||
|
||||
@ -355,7 +297,7 @@ def is_app_running():
|
||||
if WebUI is None:
|
||||
err_library_not_found('is_app_running')
|
||||
return
|
||||
r = bool(WebUI.webui_is_app_running())
|
||||
r = bool(WebUI.webui_interface_is_app_running())
|
||||
return r
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
# This script is for debugging & development of the WebUI Python wrapper
|
||||
# The source code is located at 'webui/examples/Python/PyPI/Package/src/webui/webui.py'
|
||||
# This script is for debugging & the development of the WebUI Python wrapper.
|
||||
# The wrapper source code is located at 'webui/examples/Python/PyPI/Package/src/webui/webui.py'
|
||||
|
||||
# [!] Make sure to remove the WebUI package
|
||||
# pip uninstall webui2
|
||||
@ -10,16 +10,14 @@ sys.path.append('Package/src/webui')
|
||||
import webui
|
||||
|
||||
# Use the local WebUI Dynamic lib
|
||||
# For instructions on compiling it please visit:
|
||||
# https://github.com/alifcommunity/webui/tree/main/build
|
||||
webui.set_library_path('../../../build/Windows/GCC')
|
||||
webui.set_library_path('../../../build/Windows/MSVC')
|
||||
|
||||
# HTML
|
||||
html = """
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>WebUI 2 - Python Debug & Development</title>
|
||||
<title>WebUI 2 - Python Wrapper Test</title>
|
||||
<style>
|
||||
body {
|
||||
color: white;
|
||||
@ -33,52 +31,58 @@ html = """
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Python Debug & Development</h2>
|
||||
<h2>Python Wrapper Test</h2>
|
||||
<br>
|
||||
<input type="text" id="MyInput" OnKeyUp="document.getElementById('err').innerHTML=' ';" autocomplete="off" value=\"2\">
|
||||
<br>
|
||||
<h3 id="err" style="color: #dbdd52"> </h3>
|
||||
<br>
|
||||
<button id="TestID">Test Python-To-JS</button>
|
||||
<button id="P2JS">Test Python-To-JS</button>
|
||||
<button OnClick="MyJS();">Test JS-To-Python</button>
|
||||
<button id="ExitID">Exit</button>
|
||||
<script>
|
||||
function MyJS() {
|
||||
const number = document.getElementById('MyInput').value;
|
||||
var result = webui_fn('Test2', number);
|
||||
var result = webui_fn('JS2P', number);
|
||||
document.getElementById('MyInput').value = result;
|
||||
}
|
||||
</script>
|
||||
</body></html>
|
||||
"""
|
||||
|
||||
def test(e : webui.event):
|
||||
print('Element_id: ' + str(e.element_id))
|
||||
print('Window_id: ' + str(e.window_id))
|
||||
print('Element_name: ' + e.element_name)
|
||||
def all_events(e : webui.event):
|
||||
print('Function: all_events()')
|
||||
print('Element: ' + e.Element)
|
||||
print('EventType: ' + e.EventType)
|
||||
print('Data: ' + e.Data)
|
||||
|
||||
def python_to_js(e : webui.event):
|
||||
print('Function: python_to_js()')
|
||||
print('Element: ' + e.Element)
|
||||
print('EventType: ' + e.EventType)
|
||||
print('Data: ' + e.Data)
|
||||
# Run JavaScript to get the password
|
||||
res = e.window.run_js("return document.getElementById('MyInput').value;")
|
||||
|
||||
res = e.window.script("return document.getElementById('MyInput').value;")
|
||||
# Check for any error
|
||||
if res.error is True:
|
||||
print("JavaScript Error -> Output: [" + res.data + "]")
|
||||
else:
|
||||
print("JavaScript OK -> Output: [" + res.data + "]")
|
||||
|
||||
def test2(e : webui.event):
|
||||
print('Element_id: ' + str(e.element_id))
|
||||
print('Window_id: ' + str(e.window_id))
|
||||
print('Element_name: ' + e.element_name)
|
||||
print('Data: ' + e.data)
|
||||
def js_to_python(e : webui.event):
|
||||
print('Function: js_to_python()')
|
||||
print('Element: ' + e.Element)
|
||||
print('EventType: ' + e.EventType)
|
||||
print('Data: ' + e.Data)
|
||||
v = int(e.data)
|
||||
v = v * 2
|
||||
return v
|
||||
|
||||
def close(e : webui.event):
|
||||
print('Element_id: ' + str(e.element_id))
|
||||
print('Window_id: ' + str(e.window_id))
|
||||
print('Element_name: ' + e.element_name)
|
||||
def exit(e : webui.event):
|
||||
print('Function: exit()')
|
||||
print('Element: ' + e.Element)
|
||||
print('EventType: ' + e.EventType)
|
||||
print('Data: ' + e.Data)
|
||||
webui.exit()
|
||||
|
||||
def main():
|
||||
@ -87,9 +91,10 @@ def main():
|
||||
MyWindow = webui.window()
|
||||
|
||||
# Bind am HTML element ID with a python function
|
||||
MyWindow.bind('', test)
|
||||
MyWindow.bind('Test2', test2)
|
||||
MyWindow.bind('ExitID', close)
|
||||
MyWindow.bind('', all_events)
|
||||
MyWindow.bind('P2JS', python_to_js)
|
||||
MyWindow.bind('JS2P', js_to_python)
|
||||
MyWindow.bind('Exit', exit)
|
||||
|
||||
# Show the window
|
||||
MyWindow.show(html)
|
||||
|
Binary file not shown.
@ -177,9 +177,9 @@ WEBUI_EXPORT void webui_return_string(webui_event_t* e, char* s);
|
||||
WEBUI_EXPORT void webui_return_bool(webui_event_t* e, bool b);
|
||||
|
||||
// -- Interface -----------------------
|
||||
// Bind a specific html element click event with a function. Empty element means all events. This replace webui_bind().
|
||||
// Bind a specific html element click event with a function. Empty element means all events. This replace webui_bind(). The func is (Window, EventType, Element, Data, Response)
|
||||
WEBUI_EXPORT unsigned int webui_interface_bind(void* window, const char* element, void (*func)(void*, unsigned int, char*, char*, char*));
|
||||
// When using `webui_interface_bind()` you need this function to easily set your response.
|
||||
// When using `webui_interface_bind()` you need this function to easily set your callback response.
|
||||
WEBUI_EXPORT void webui_interface_set_response(char* ptr, const char* response);
|
||||
// Check if the app still running or not. This replace webui_wait().
|
||||
WEBUI_EXPORT bool webui_interface_is_app_running(void);
|
||||
|
Loading…
x
Reference in New Issue
Block a user