太赞了!别再说 不克不及用Python开发美看的GUI法式了!
比来不断在测验考试 Python GUI 的相关功用,也有了一些体味心得
Tkinter Designer需要进修Figma那款设想软件若何利用,其美化GUI的原理就是用图片往填充,从而让Tkinter有比力美看的款式,抱愧,我暂时还不想学Figma。
而别的一个计划:TTk Bootstrap其实是更大的坑,假设你只是开发单窗口GUI软件,TTkBootstrap挺好的,但当你有开启一个窗口后,封闭并开启别的一个新窗口的需求时,TTKBoostrap就是一个大坑,新的窗口会丧失掉响应的款式。
我期看Python生态中有类似Electron的库,让我们能够操纵HTML、CSS、JS来构建前端页面,然后端的逻辑利用Python来实现,如许就能够轻松构建出美看的GUI了。
有我微信老友的伴侣应该晓得,上两周我搀扶帮助各人将视频一键同步到6个差别的媒体平台,那个软件便利用PyWebView框架开发,软件界面如下:
PyWebView能够让你通过HTML、CSS、JS来构建GUI的前端页面,利用Python来实现软件中的营业逻辑,再共同利用Pyinstaller实现软件打包,即可以构建一个美看的GUI利用了。
遗憾的是PyWebView材料比力少,Github的star数也不多,我现实操做下来,有些Windows平台无法翻开,因精神有限,也没有往深究为何无法翻开。
本文便简单介绍PyWebView的利用办法,比拟于官方文档,会凸起此中碰着的坑和响应的处理计划, 也算是视频同步助手那个项目标手艺复盘吧(嗯,变现阶段失败了,所以)。
简单利用
光读PyWebView的文档,是比力难起步的,比力好的体例是往PyWebView的github中将源码拉下来,此中有example目次,供给了一下例子项目,此中要搞懂的核心逻辑是, 前端JS写的逻辑,怎么往与Python互通。
PyWebView供给了js api和接口恳求那两种办法,先看js api。
JS api
在实例化webview时,将定义好的Api类实例做为js_api的参数传进:
classApi:
defaddItem(self, title):
print( 'Added item %s'% title)
defremoveItem(self, item):
print( 'Removed item %s'% item)
defeditItem(self, item):
print( 'Edited item %s'% item)
deftoggleItem(self, item):
print( 'Toggled item %s'% item)
deftoggleFullscreen(self):
webview.windows[ 0].toggle_fullscreen
defload_page(self):
file_url = 'file:///C:/Users/admin/workplace/github/pywebview/examples/todos/assets/hello.html'
webview.windows[ 0].load_url(file_url)
if__name__ == '__main__':
api = Api
# js_api 获得 api 实例
webview.create_window( 'Todos magnificos', 'assets/index.html', js_api=api, min_size=( 600, 450))
webview.start(debug= True)
前端通过window.pywebview.api来利用Api类中供给的办法,好比挪用addItem办法:
window.pywebview.api.addItem(title)
因为我们项目在启动时,开启了debug形式,所以能够按F12翻开阅读器的DevTools,在掌握台中,能够轻松打印出window.pywebview中各类属性,此中的api属性包罗了Python中Api类供给的所有办法。
HTTP办事
JS api关于一些比力复杂的需求不太好用,此时能够利用办事。
起首,基于Flask构建办事实例:
fromflask importFlask
server = Flask(__name__, static_folder=gui_dir, template_folder=gui_dir)
然后再实例化webview:
# 传进server实例,开启HTTP办事形式
window = webview.create_window( 'My first pywebview application', server)
webview.start(debug= True)
前端JS通过Ajax的形式,恳求Flask供给的接口,从而让后端施行相关的逻辑,假设没有利用Vue、React等框架时,我小我便习惯利用Jquery供给的ajax办法,并在该办法根底上再封拆多一层。
functiondoAjax( url, method, data, success, fail) {
if(success === undefined) {
success = function( data) {
console.log( '[success] ', data)
if(fail === undefined) {
fail = function( err) {
console.log( '[fail]', err)
if(method === 'POST') {
data = JSON.stringify(data)
$.ajax({
url: url,
type: method,
cache: false,
dataType: "json",
headers: {
"token": window.token
data: data,
contentType: "application/json; charset=utf-8",
success: success,
fail: fail
在需要挪用后端逻辑时,间接恳求接口则可:
functionget_video_settings_data( video_id) {
doAjax( "/video_settings/data", "GET", { video_id: video_id}, get_video_settings_data_handler);
与之对应的后端接口与通俗的Flask接口没啥差别:
@server.route('/video_settings/data', methods=['GET'])
defget_video_settings_data:
video_id = request.args.get( 'video_id')
video_id = video_id.split( '-')[ -1]
data = VideoTaskSettingsModel.get_settings(video_id=video_id)
ifnotdata:
video_settings = {}
else:
video_settings = data[ 0]
returnjsonify({ 'status': 'ok', 'video_settings': video_settings})
importwebview
defverify_token(function):
@wraps(function)
defwrapper(*args, **kwargs):
token = request.headers.get( 'token')
# 揣度前端传递token能否与webview.token一致,从而校验恳求能否合法
iftoken == webview.token:
returnfunction(*args, **kwargs)
else:
raiseException( 'Authentication error')
returnwrapper
@server.route('/video/task_list')
@verify_token
defvideo_task_list:
视频设置装备摆设列表
:return:
video_tasks = VideoTaskModel.get_all_video_task
response = {
'status': 'ok',
'video_tasks': video_tasks
returnjsonify(response)
简易路由
在开发视频同步助手时,为了便利,没有利用Vue+PyWebView的形式,即我无法利用类似vue-router的工具来实现页面改变的效果,那要怎么弄呢?
视频同步助手前端操纵Flask的模板语法+Jquery实现次要逻辑,后端就是Flask+JS Api,没错,PyWebView容许你同时开启撑持。
为了实现页面的改变,我将侧边栏那些都写到base.html中,然后通过Flask模板继续的才能制止每个页面中都弄个侧边栏。
当我们要拜候差别页面时,发现PyWebView不容许你通过render_template办法获得新页面,PyWebView要实现页面更新只要两种体例,一是利用load_url办法,供给一个url,webview会往加载新的页面,另一种是利用load_html办法,该办法会加载html文件。
遗憾的是,load_html办法加载html时,不会施行html中引进的JS,所以我们只能通过load_url办法往做。
回忆一下PyWebView 才气获取。
为领会决那个问题,只能在PyWebView刚启动时,将url笔录起来,然后再操纵笔录的url拼接出完全的URL,实现页面的切换。
PyWebView启动后,假设开启了:
@server.route('/')
defvideo_task_template:
视频使命
set_base_url(request.base_url)
# 省略...
共同JS Api,来挪用load_url办法:
classJSApi:
defload_page(self, page_name):
url = urljoin(get_base_url, page_name)
webview.windows[ 0].load_url(url)
用户点击侧边栏时,利用JSApi供给的load_page办法:
window.token = '{{ token }}';
function view_video_task {
window.pywebview.api.load_page('/')
function view_user {
window.pywebview.api.load_page('/user_template')
Flask中配到接口,通过render_template返回页面数据:
@server.route('/user_template')
defuser_template:
用户列表
set_base_url(request.base_url)
returnrender_template( 'user.html', token=webview.token)
通过那种体例,操纵了PyWebView的load_url办法,胜利加载新页面,实现页面的切换,页面中的JS也能够一般施行。
视频元素展现
用户需要添加本身的视频到无感同步助手中,会发现,视频元素无法展现,其原因在于,视频可能在用户系统的肆意位置,当前Flask构建的web办事因为平安沙箱的原因,无法读取系统中肆意位置的元素并返回。
我们看到Flask实例化时,需要传输static_folder,我们才气一般拜候存放在static_folder中的js、css文件,template_folder也是一个事理。
frontend_dir = os.path.join(root_path, 'gui', 'frontend')
server = Flask(__name__, static_folder=frontend_dir, template_folder=frontend_dir)
我们能否能够为Flask添加多个static,从而实现让Flask能够拜候系统中肆意元素的效果呢?嗯,能够的,操纵Flask供给的send_from_directory办法。
fromflask importrequest, send_from_directory
@server.route('/cdn')
defcustom_static:
file_dir_path = request.args.get( 'file_dir_path')
filename = request.args.get( 'filename')
returnsend_from_directory(file_dir_path, filename)
前端拜候的形式为:
divclass= "video-source-div"
videoclass= "video-source"controls= ""
sourceid= "video-srouce-5"src= "cdn?file_dir_path=C:\Users\admin\Videos\myvideosfilename=无感助手开发深思.mp4"metadata= ""preload= "auto"type= "video/mp4" / source
/ video
/ div
JS无法开启新Tab
无感同步助手的营业逻辑中,有开启新Tab页面的需求,网上常见的处理办法为:
window.open( '')
一般而言,那会开启一个新的Tab,但Chrome为了制止网站歹意开启新的Tab,默认是不容许纯JS开启新Tab的操做的。
怎么处理?翻了大半天Chrome的文档,才晓得庇护window.open无效以及处理办法。
拜候Chrome中关于弹出窗口的设置:chrome://settings/content/popups
然后将默认修改改成【网站能够发送弹出式窗口并利用重定向】则可。
结尾
PyWebView会利用系统自带的阅读器内核来给你的GUI法式供给前端展现,而Electron是本身打包进一个Chromium,所以PyWebView打包会小一点,但不变性上,小我体验下来,比Electron差上一些。
此外,Pyinstaller打包也是一个大坑,后续有空,再将Pyinstaller的各类理论身手补上。
好了,那就是今天禀享的全数内容,喜好就点个 赞吧~
进门: 最全的零根底学Python的问题 | 零根底学了8个月的Python |实战项目 | 学Python就是那条捷径
干货:爬取豆瓣短评,片子《后来的我们》 | 38年NBA更佳球员阐发 |从万寡等待到口碑扑街!唐探3令人失看 | 笑看新倚天屠龙记 | 灯谜答题王 | 用Python做个海量蜜斯姐素描图 | 碟中谍那么火,我用机器进修做个迷你选举系统片子
兴趣:弹球游戏 | 九宫格 | 标致的花 | 两百行Python《天天酷跑》游戏!
AI:会做诗的机器人 | 给图片上色 | 揣测收进 | 碟中谍那么火,我用机器进修做个迷你选举系统片子
小东西: Pdf转Word,轻松搞定表格和水印! | 一键把html网页保留为pdf! |再见PDF提取收费! | 用90行代码打造最强PDF转换器,word、PPT、excel、markdown、html一键转换 | 造造一款钉钉低价机票提醒器! |60行代码做了一个语音壁纸切换器天天看蜜斯姐! |
年度爆款案牍
1). 卧槽!Pdf转Word用Python轻松搞定 !
2).学Python实香!我用100行代码做了个网站,帮人PS游览图片,赚个鸡腿食
3).首播过亿,火爆全网,我阐发了《披荆斩棘的姐姐》,发现了那些奥秘
4). 80行代码!用Python做一个哆来A梦分身
5).你必需掌握的20个python代码,短小精悍,用途无限
6). 30个Python奇淫身手集
7). 我总结的80页《菜鸟学Python精选干货.pdf》,都是干货
8). 再见Python!我要学Go了!2500字深度阐发 !
9).发现一个舔狗福利!那个Python爬虫神器太爽了,主动下载妹子图片