parent
e0be6fefd5
commit
fa542e57f1
45
README.md
45
README.md
|
@ -1,3 +1,44 @@
|
|||
# pyweb
|
||||
# pyweb 🚀
|
||||
|
||||
一个基于Pywebview构建的开箱即用的模板
|
||||
## 📝 项目介绍
|
||||
|
||||
pyweb是一个基于Pywebview构建的开箱即用的模板,旨在帮助快速搭建Python Web应用程序。它提供了一个简单的界面,可以轻松地将Python代码与Web界面结合起来,使得开发人员可以更加专注于业务逻辑的实现。
|
||||
|
||||
## ✨ 功能列表
|
||||
|
||||
- [x] 界面展示
|
||||
- [x] 数据处理
|
||||
- [x] 用户认证
|
||||
- [x] 数据库集成
|
||||
- [ ] 数据可视化
|
||||
- [ ] 文件上传和下载
|
||||
|
||||
## 📦 安装
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
## ▶️ 启动
|
||||
|
||||
```bash
|
||||
python run main.py
|
||||
```
|
||||
|
||||
## 📷 截屏
|
||||
|
||||
<!-- ![截屏](screenshot.png) -->
|
||||
|
||||
## 🤝 贡献
|
||||
|
||||
欢迎贡献代码!请遵循以下步骤:
|
||||
|
||||
1. Fork本仓库
|
||||
2. 创建您的分支 (`git checkout -b feature/AmazingFeature`)
|
||||
3. 提交您的更改 (`git commit -am 'Add some AmazingFeature'`)
|
||||
4. 推送到分支 (`git push origin feature/AmazingFeature`)
|
||||
5. 打开一个Pull请求
|
||||
|
||||
## 📄 许可
|
||||
|
||||
本项目采用MIT许可证,详情请参阅[LICENSE](LICENSE)文件。
|
|
@ -0,0 +1,14 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
# @File : gui
|
||||
# @Time : 2024-01-02 01:59:36
|
||||
# @Docs : WebGUI
|
||||
|
||||
import webview
|
||||
|
||||
# 创建一个窗口
|
||||
webview.create_window(
|
||||
'Hello world',
|
||||
'https://pywebview.flowrl.com/',
|
||||
)
|
||||
# 启动程序
|
||||
webview.start()
|
Binary file not shown.
After Width: | Height: | Size: 327 KiB |
|
@ -0,0 +1,32 @@
|
|||
import webview
|
||||
|
||||
|
||||
def lol():
|
||||
print('LOL')
|
||||
|
||||
|
||||
def wtf():
|
||||
print('WTF')
|
||||
|
||||
|
||||
def echo(arg1, arg2, arg3):
|
||||
print(arg1)
|
||||
print(arg2)
|
||||
print(arg3)
|
||||
|
||||
|
||||
def expose(window):
|
||||
window.expose(echo) # expose a function during the runtime
|
||||
|
||||
window.evaluate_js('pywebview.api.lol()')
|
||||
window.evaluate_js('pywebview.api.wtf()')
|
||||
window.evaluate_js('pywebview.api.echo(1, 2, 3)')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
window = webview.create_window(
|
||||
'JS Expose Example', html='<html><head></head><body><h1>JS Expost</body></html>'
|
||||
)
|
||||
window.expose(lol, wtf) # expose functions beforehand
|
||||
|
||||
webview.start(expose, window, debug=True)
|
|
@ -0,0 +1,20 @@
|
|||
import webview
|
||||
from webview import Window
|
||||
|
||||
|
||||
def save_file_dialog(window: Window):
|
||||
import time
|
||||
|
||||
time.sleep(5)
|
||||
result = window.create_file_dialog(
|
||||
webview.SAVE_DIALOG, directory='/', save_filename='test.file'
|
||||
)
|
||||
print(result)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
window = webview.create_window(
|
||||
'Save file dialog',
|
||||
'https://pywebview.flowrl.com/hello',
|
||||
)
|
||||
webview.start(save_file_dialog, window)
|
|
@ -0,0 +1,17 @@
|
|||
import time
|
||||
import webview
|
||||
|
||||
|
||||
def toggle_fullscreen(window):
|
||||
# wait a few seconds before toggle fullscreen:
|
||||
time.sleep(5)
|
||||
|
||||
window.toggle_fullscreen()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
window = webview.create_window(
|
||||
'Full-screen window',
|
||||
'https://pywebview.flowrl.com/hello',
|
||||
)
|
||||
webview.start(toggle_fullscreen, window)
|
|
@ -0,0 +1,101 @@
|
|||
import bottle
|
||||
|
||||
import webview
|
||||
|
||||
# We'll have a global list of our windows so our web app can give us information
|
||||
# about them
|
||||
windows = []
|
||||
|
||||
# A simple function to format a description of our servers
|
||||
|
||||
|
||||
def serverDescription(server):
|
||||
return f"{str(server).replace('<','').replace('>','')}"
|
||||
|
||||
|
||||
# Define a couple of simple web apps using Bottle
|
||||
app1 = bottle.Bottle()
|
||||
|
||||
|
||||
@app1.route('/')
|
||||
def hello():
|
||||
return '<h1>Second Window</h1><p>This one is a web app and has its own server.</p>'
|
||||
|
||||
|
||||
app2 = bottle.Bottle()
|
||||
|
||||
|
||||
@app2.route('/')
|
||||
def hello():
|
||||
head = """ <head>
|
||||
<style type="text/css">
|
||||
table {
|
||||
font-family: arial, sans-serif;
|
||||
border-collapse: collapse;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
td, th {
|
||||
border: 1px solid #dddddd;
|
||||
text-align: center;
|
||||
padding: 8px;
|
||||
}
|
||||
|
||||
tr:nth-child(even) {
|
||||
background-color: #dddddd;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
"""
|
||||
body = f""" <body>
|
||||
<h1>Third Window</h1>
|
||||
<p>This one is another web app and has its own server. It was started after webview.start.</p>
|
||||
<p>Server Descriptions: </p>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Window</th>
|
||||
<th>Object</th>
|
||||
<th>IP Address</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Global Server</td>
|
||||
<td>{serverDescription(webview.http.global_server)}</td>
|
||||
<td>{webview.http.global_server.address if not webview.http.global_server is None else 'None'}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>First Window</td>
|
||||
<td>{serverDescription(windows[0]._server)}</td>
|
||||
<td>{windows[0]._server.address if not windows[0]._server is None else 'None'}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Second Window</td>
|
||||
<td>{serverDescription(windows[1]._server)}</td>
|
||||
<td>{windows[1]._server.address}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Third Window</td>
|
||||
<td>{serverDescription(windows[2]._server)}</td>
|
||||
<td>{windows[2]._server.address}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body>
|
||||
"""
|
||||
return head + body
|
||||
|
||||
|
||||
def third_window():
|
||||
# Create a new window after the loop started
|
||||
windows.append(webview.create_window('Window #3', url=app2))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Master window
|
||||
windows.append(
|
||||
webview.create_window(
|
||||
'Window #1',
|
||||
html='<h1>First window</h1><p>This one is static HTML and just uses the global server for api calls.</p>',
|
||||
)
|
||||
)
|
||||
windows.append(webview.create_window(
|
||||
'Window #2', url=app1, http_port=3333))
|
||||
webview.start(third_window, debug=True, http_server=True, http_port=3334)
|
|
@ -0,0 +1,16 @@
|
|||
import webview
|
||||
|
||||
|
||||
def third_window():
|
||||
# Create a new window after the loop started
|
||||
third_window = webview.create_window(
|
||||
'Window #3', html='<h1>Third Window</h1>')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Master window
|
||||
master_window = webview.create_window(
|
||||
'Window #1', html='<h1>First window</h1>')
|
||||
second_window = webview.create_window(
|
||||
'Window #2', html='<h1>Second window</h1>')
|
||||
webview.start(third_window)
|
|
@ -0,0 +1,11 @@
|
|||
import webview
|
||||
|
||||
if __name__ == '__main__':
|
||||
screens = webview.screens
|
||||
print('Available screens are: ' + str(screens))
|
||||
|
||||
for i, screen in enumerate(screens):
|
||||
webview.create_window(
|
||||
'', html=f'placed on the monitor {i+1}', screen=screen)
|
||||
|
||||
webview.start()
|
|
@ -0,0 +1,16 @@
|
|||
import webview
|
||||
|
||||
|
||||
def open_file_dialog(window):
|
||||
file_types = ('Image Files (*.bmp;*.jpg;*.gif)', 'All files (*.*)')
|
||||
|
||||
result = window.create_file_dialog(
|
||||
webview.OPEN_DIALOG, allow_multiple=True, file_types=file_types
|
||||
)
|
||||
print(result)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
window = webview.create_window(
|
||||
'Open file dialog example', 'https://pywebview.flowrl.com/hello')
|
||||
webview.start(open_file_dialog, window)
|
|
@ -0,0 +1,48 @@
|
|||
import multiprocessing
|
||||
import sys
|
||||
|
||||
from PIL import Image
|
||||
from pystray import Icon, Menu, MenuItem
|
||||
|
||||
import webview
|
||||
|
||||
if sys.platform == 'darwin':
|
||||
ctx = multiprocessing.get_context('spawn')
|
||||
Process = ctx.Process
|
||||
Queue = ctx.Queue
|
||||
else:
|
||||
Process = multiprocessing.Process
|
||||
Queue = multiprocessing.Queue
|
||||
|
||||
webview_process = None
|
||||
|
||||
|
||||
def run_webview():
|
||||
window = webview.create_window(
|
||||
'Webview', 'https://pywebview.flowrl.com/hello')
|
||||
webview.start()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
def start_webview_process():
|
||||
global webview_process
|
||||
webview_process = Process(target=run_webview)
|
||||
webview_process.start()
|
||||
|
||||
def on_open(icon, item):
|
||||
global webview_process
|
||||
if not webview_process.is_alive():
|
||||
start_webview_process()
|
||||
|
||||
def on_exit(icon, item):
|
||||
icon.stop()
|
||||
|
||||
start_webview_process()
|
||||
|
||||
image = Image.open('./logo/logo.jpg')
|
||||
menu = Menu(MenuItem('Open', on_open), MenuItem('Exit', on_exit))
|
||||
icon = Icon('Pystray', image, menu=menu)
|
||||
icon.run()
|
||||
|
||||
webview_process.terminate()
|
|
@ -0,0 +1,36 @@
|
|||
import webview
|
||||
from webview import Window
|
||||
|
||||
html = """
|
||||
<head>
|
||||
<style type="text/css">
|
||||
.pywebview-drag-region {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
margin-top: 50px;
|
||||
margin-left: 50px;
|
||||
background: orange;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="pywebview-drag-region">Drag me!</div>
|
||||
<button onclick="pywebview.api()">点击</button>
|
||||
</body>
|
||||
"""
|
||||
|
||||
|
||||
def close(window: Window):
|
||||
print("Hello World!")
|
||||
window.destroy()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
window = webview.create_window(
|
||||
'API example',
|
||||
html=html,
|
||||
frameless=True,
|
||||
easy_drag=False,
|
||||
)
|
||||
window.expose(close)
|
||||
webview.start()
|
|
@ -0,0 +1,12 @@
|
|||
import webview
|
||||
|
||||
if __name__ == '__main__':
|
||||
webview.create_window(
|
||||
'User Agent Test',
|
||||
'https://pywebview.flowrl.com/hello',
|
||||
# frameless=True, easy_drag=True,
|
||||
)
|
||||
webview.start(
|
||||
user_agent='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0',
|
||||
|
||||
)
|
|
@ -0,0 +1,62 @@
|
|||
import webview
|
||||
import webview.menu as wm
|
||||
|
||||
|
||||
def change_active_window_content():
|
||||
active_window = webview.active_window()
|
||||
if active_window:
|
||||
active_window.load_html('<h1>You changed this window!</h1>')
|
||||
|
||||
|
||||
def click_me():
|
||||
active_window = webview.active_window()
|
||||
if active_window:
|
||||
active_window.load_html('<h1>You clicked me!</h1>')
|
||||
|
||||
|
||||
def do_nothing():
|
||||
pass
|
||||
|
||||
|
||||
def say_this_is_window_2():
|
||||
active_window = webview.active_window()
|
||||
if active_window:
|
||||
active_window.load_html('<h1>This is window 2</h2>')
|
||||
|
||||
|
||||
def open_file_dialog():
|
||||
active_window = webview.active_window()
|
||||
active_window.create_file_dialog(
|
||||
webview.SAVE_DIALOG, directory='/', save_filename='test.file')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
window_1 = webview.create_window(
|
||||
'Application Menu Example', 'https://pywebview.flowrl.com/hello'
|
||||
)
|
||||
window_2 = webview.create_window(
|
||||
'Another Window', html='<h1>Another window to test application menu</h1>'
|
||||
)
|
||||
|
||||
menu_items = [
|
||||
wm.Menu(
|
||||
'Test Menu',
|
||||
[
|
||||
wm.MenuAction('Change Active Window Content',
|
||||
change_active_window_content),
|
||||
wm.MenuSeparator(),
|
||||
wm.Menu(
|
||||
'Random',
|
||||
[
|
||||
wm.MenuAction('Click Me', click_me),
|
||||
wm.MenuAction('File Dialog', open_file_dialog),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
wm.Menu('Nothing Here', [wm.MenuAction(
|
||||
'This will do nothing', do_nothing)],
|
||||
),
|
||||
]
|
||||
|
||||
webview.start(menu=menu_items)
|
|
@ -0,0 +1,16 @@
|
|||
from time import sleep
|
||||
import webview
|
||||
|
||||
|
||||
def resize(window):
|
||||
print('Window size is ({0}, {1})'.format(window.width, window.height))
|
||||
sleep(2)
|
||||
window.resize(420, 420)
|
||||
print('Window size is ({0}, {1})'.format(window.width, window.height))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
window = webview.create_window(
|
||||
'Resize window example', html='<h1>Resize window</h1>', width=800, height=600
|
||||
)
|
||||
webview.start(resize, window)
|
|
@ -0,0 +1,72 @@
|
|||
import webview
|
||||
|
||||
html = """
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test app</title>
|
||||
<style>
|
||||
.frame {
|
||||
border-radius: 5px 5px 0 0;
|
||||
position: fixed;
|
||||
box-sizing: border-box;
|
||||
width: 90%;
|
||||
height: 90%;
|
||||
background-color: #0055e4;
|
||||
box-shadow: inset 1px 1px 1px 0px rgba(255,255,255,.25), inset -1px -1px 1px 0px rgba(0,0,0,.25), inset 0px 2px 4px -2px rgba(255,255,255,1);
|
||||
}
|
||||
.frame>tbody>tr>td {
|
||||
vertical-align: top;
|
||||
}
|
||||
.header {
|
||||
box-sizing: border-box;
|
||||
padding: 5px;
|
||||
height: 20px;
|
||||
font-weight: bold;
|
||||
color: white;
|
||||
}
|
||||
.header>img {
|
||||
height: 16px;
|
||||
transform: translateY(3px);
|
||||
}
|
||||
.content {
|
||||
box-sizing: border-box;
|
||||
background-color: #f0f0e8;
|
||||
margin: 0 5px 5px 5px ;
|
||||
}
|
||||
.bodypanel {
|
||||
background-color: #f0f0e8;
|
||||
height: 100%;
|
||||
box-shadow: 1px 1px 1px 0px rgba(255,255,255,.25), -1px -1px 1px 0px rgba(0,0,0,.25), inset 0px 0px 3px -2px rgba(0,0,0,1);
|
||||
padding: 5px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<table class="frame">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td class="header">
|
||||
<img src="folder.png"/>
|
||||
Danger!
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td class="body">
|
||||
<div class="bodypanel">
|
||||
<b>Alert!</b><br>
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
if __name__ == '__main__':
|
||||
# Create a transparent webview window
|
||||
webview.create_window('Transparent window', html=html, transparent=True, frameless=True)
|
||||
webview.start()
|
Loading…
Reference in New Issue