streamlit+pywebview,纯python以前后端形式写桌面应用

news2024/11/16 0:43:37

1、VSCode

VSCode
VSCode扩展:Python

2、配置PowerShell执行策略

以管理员身份运行PowerShell,运行Set-ExecutionPolicy RemoteSigned,并输入Y,回车确认

3、配置Python环境

  1. 只安装Python:华为镜像、阿里镜像、newbe、Python官网ftp地址、Python官网中文页面
  2. Python嵌入版:Python3.11.3下载页面、Python3.11.3嵌入版下载直链、各个镜像的嵌入式压缩包
  3. 虚拟环境或版本管理:venv、virtualenv、virtualenvwrapper、poetry、conda、Anaconda、Miniconda清华镜像、pyenv-win的Github仓库、pyenv-virtualenv、pipenv

在streamlit的入门文档中,支持的 Python 版本为 3.7 - 3.11

本篇文章使用嵌入式Python3.11.3 64位python-3.11.3-embed-amd64.zip
解压为python-3.11.3-embed-amd64文件夹,改名为python3.11.3-e

4、调整项目结构

新建文件夹histreamlit,将python3.11.3-e放到histreamlit文件夹内
路径:histreamlit\python3.11.3-e

新建子文件夹histreamlit,路径:histreamlit\histreamlit
添加一个ico格式图片,路径:histreamlit\2530812_crest_crown_general_item_jwellery_icon.ico
在这里插入图片描述

5、继续配置Python环境

.\python3.11.3-e\pip.ini,新建该文件,内容如下

[global]
index-url = https://mirrors.aliyun.com/pypi/simple
trusted-host = mirrors.aliyun.com
timeout = 120

下载get-pip.py,放进python3.11.3-e文件夹
运行.\python3.11.3-e\python.exe .\python3.11.3-e\get-pip.py

编辑histreamlit\python3.11.3-e\python311._pth文件,将#import site改为import site

安装black
.\python3.11.3-e\python.exe -m pip install -U black --user

6、安装streamlit

.\python3.11.3-e\python.exe -m pip install streamlit

7、运行streamlit自带hello项目

.\python3.11.3-e\Scripts\streamlit.exe hello
在这里插入图片描述
自动启动浏览器显示界面
在这里插入图片描述
Ctrl+C停止运行(反应极慢,不如直接关了命令行窗口另开一个)

8、复制一下官方demo

在这里插入图片描述
新建文件histreamlit\histreamlit\main.py
在这里插入图片描述
使用 VSCode 打开histreamlit文件夹,右下角选择解释器,点击Enter interpreter path…,点击Find…,选择.\python3.11.3-e\python.exe,点击Select Interpreter

编辑文件histreamlit\histreamlit\main.py(复制一下官方的demo)

import streamlit as st
import numpy as np
import time

progress_bar = st.sidebar.progress(0)
status_text = st.sidebar.empty()
last_rows = np.random.randn(1, 1)
chart = st.line_chart(last_rows)

for i in range(1, 101):
    new_rows = last_rows[-1, :] + np.random.randn(5, 1).cumsum(axis=0)
    status_text.text("%i%% Complete" % i)
    chart.add_rows(new_rows)
    progress_bar.progress(i)
    last_rows = new_rows
    time.sleep(0.05)

progress_bar.empty()

# Streamlit widgets automatically run the script from top to bottom. Since
# this button is not connected to any other logic, it just causes a plain
# rerun.
st.button("Re-run")

9、运行

运行.\python3.11.3-e\Scripts\streamlit.exe run .\histreamlit\main.py

10、静默运行,不启动浏览器

运行.\python3.11.3-e\Scripts\streamlit.exe run .\histreamlit\main.py --server.headless=true --browser.serverAddress="localhost"

11、安装PyWebview

.\python3.11.3-e\Scripts\pip.exe install pywebview

12、新建文件pwv.py

histreamlit\histreamlit\pwv.py

import webview
import streamlit.web.bootstrap as bootstrap
import multiprocessing as mp
from multiprocessing import Process
import socket
from http.server import HTTPServer
import os
import signal


def check_port_in_use(port):
    try:
        # 创建一个HTTPServer实例
        httpd = HTTPServer(("", port), None)
        # 关闭HTTPServer实例
        httpd.server_close()
        # 如果没有抛出异常,说明端口可以使用
        return False
    except socket.error:
        # 如果抛出异常,说明端口已经被占用
        return True


def guess_streamlit_port():
    for p in range(8501, 8601):
        if not check_port_in_use(p):
            # print(f"端口 {p} 可以使用")
            return p
        else:
            # print(f"端口 {p} 已被使用")
            pass


def stre(q: mp.Queue):
    q.put(os.getpid())

    # .\python3.11.3-e\Scripts\streamlit.exe run .\histreamlit\main.py --server.headless=true --browser.serverAddress="localhost"
    flag_options = {
        "server.headless": True,
        "global.developmentMode": False,
        "browser.serverAddress": "localhost",
    }
    bootstrap.load_config_options(flag_options=flag_options)
    flag_options["_is_running_with_streamlit"] = True
    bootstrap.run(
        "main.py", "../python3.11.3-e/Scripts/streamlit.exe run", [], flag_options
    )


def webv(q: mp.Queue, port):
    q.put(os.getpid())

    def on_closing():
        print("Closing window...")

        pids = [q.get(), q.get()]
        # 分辨出哪个是streamlit,将streamlit放到第0位
        if pids[0] == os.getpid():
            pids.reverse()
        pids.append(os.getppid())

        for p in pids:
            os.kill(p, signal.SIGTERM)
        # return True 表示webview将关闭。不过无所谓,满门抄斩了已经
        return True

    win = webview.create_window(
        "histreamlit", f"http://localhost:{port}/", confirm_close=True
    )
    win.events.closing += on_closing
    webview.start()


if __name__ == "__main__":
    port = guess_streamlit_port()

    q = mp.Queue()
    processes: list[Process] = []

    webv_process = mp.Process(name="webv_process", target=webv, args=((q, port)))
    webv_process.start()
    processes.append(webv_process)

    stre_process = mp.Process(name="stre_process", target=stre, args=((q,)))
    stre_process.start()
    processes.append(stre_process)

    for p in processes:
        p.join()
    pass

13、运行streamlit+pywebview

.\python3.11.3-e\python.exe .\histreamlit\pwv.py

14、运行streamlit+pywebview(bat脚本)

新建文件histreamlit\histreamlit\start.bat

@echo off
cd /d %~dp0
..\python3.11.3-e\python.exe .\pwv.py

双击start.bat运行

15、编写vbs,启动不显示控制台

histreamlit\start.vbs

set WshShell = createobject("WScript.Shell")           ' 创建一个对象引用
dim currentDir                                         ' 创建变量
currentDir = WshShell.CurrentDirectory                 ' 获取当前文件夹
WshShell.run currentDir & "/histreamlit/start.bat", 1  ' 运行bat, 0表示不显示窗口, 1表示显示窗口

histreamlit\start_noconsole.vbs

set WshShell = createobject("WScript.Shell")           ' 创建一个对象引用
dim currentDir                                         ' 创建变量
currentDir = WshShell.CurrentDirectory                 ' 获取当前文件夹
WshShell.run currentDir & "/histreamlit/start.bat", 0  ' 运行bat, 0表示不显示窗口, 1表示显示窗口

唯一的区别一个参数用的是1,另一个用的是0
分别双击vbs脚本运行

16、将vbs转换为exe

注:之前截图中带有gb18030字样的vbs只是文本编码是gb18030,因为用来vbs转exe的软件不认识utf8,注释中文字会乱码而已


start_gb18030.vbsstart.exe为例
在这里插入图片描述
勾选图标,选择ico文件
EXE格式,改为32位 | Windows(隐形),(这里的隐形是vbs的隐形,不是bat,python的窗口隐形)
勾选启用 UPX 压缩
点击工具栏的转换(圆底齿轮图标),文件名起名为start.exe保存,软件将生成exe文件
在这里插入图片描述

17、最终效果

运行start.exe
在这里插入图片描述
关闭pywebview的窗口cmd会显示一下Closing window...,然后就消失了
在这里插入图片描述
运行start_noconsole.exe是一样的,就是没有控制台窗口而已,更像一个桌面应用了

18、怎么分发

有什么可分发的,文件夹发给别人运行exe不就得了,还想咋分发,就这玩意还想加密啊,用服务器呗,肯定密



7、(失败)参考议题,制作桌面端应用

(失败原因:npm run dump histreamlit numpy一直运行个没完,输出停滞)
Streamlit - #1370议题
@stlite/desktop - README.md

8、(失败)安装nvm

访问下载地址下载安装nvm:
百度云分享
官网直装链接
nvm的github发行界面下载nvm-setup.exe
GitCode镜像下载nvm-setup.exe(登录获取下载链接,下载链接还是Github的,唯一的作用就是挑选版本的时候快点)

9、(失败)配置nvm

nvm install lts安装最新版本的Node.js,本文安装的是18.16.0
nvm use lts启用这个版本
运行cmd /c "nvm -v && node -v && npm -v",正常输出版本号说明安装完成

10、(失败)配置npm镜像

npm config set registry https://registry.npmmirror.com

11、(失败)准备使用stlite

histreamlit-ehistreamlit两个文件夹应当同级,它们是独立的

md histreamlit-e
cd .\histreamlit-e\
npm init -y
code .
将编辑文件.\histreamlit-e\package.json,改为以下内容

{
  "name": "histreamlit-e",
  "version": "0.1.0",
  "main": "./build/electron/main.js",
  "scripts": {
    "dump": "dump-stlite-desktop-artifacts",
    "serve": "cross-env NODE_ENV=production electron .",
    "pack": "electron-builder --dir",
    "dist": "electron-builder",
    "postinstall": "electron-builder install-app-deps"
  },
  "build": {
    "files": ["build/**/*"],
    "directories": {
      "buildResources": "assets"
    }
  },
  "devDependencies": {
    "@stlite/desktop": "^0.25.0",
    "cross-env": "^7.0.3",
    "electron": "23.1.1",
    "electron-builder": "^23.6.0"
  }
}

访问以下npm包,查看版本并修改package.json
在这里插入图片描述
@stlite/desktop - npm
cross-env - npm
electron - npm
electron-builder - npm
例如以下截图:
在这里插入图片描述

12、(失败)安装依赖

histreamlit-e目录中
运行cmd /c "set ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/&& npm install"

提示高危:6 high severity vulnerabilities
运行cmd /c "npm audit fix --force --registry=https://registry.npmjs.org"解决高危

13、(失败)将histreamlit的内容写进histreamlit-e

新建文件.\histreamlit-e\histreamlit\streamlit_app.py,内容与.\histreamlit\histreamlit\main.py一致

14、(失败)运行

histreamlit-e目录中
npm run dump histreamlit numpy
一直运行不完成,没有CPU或者磁盘占用,也许在下载什么东西但是没有timeout功能导致的





请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/487410.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DC-DC直流隔离升压高压输出电源模块12v24v48v转50V110V200V250V350V400V500V600V800V1000V微功率

特点 效率高达 80%以上1*2英寸标准封装单电压输出价格低稳压输出工作温度: -40℃~85℃阻燃封装,满足UL94-V0 要求温度特性好可直接焊在PCB 上 应用 HRB W2~40W 系列模块电源是一种DC-DC升压变换器。该模块电源的输入电压分为:4.5~9V、9~18V、及18~36V、…

Android 编译模块 (小记)

1.整编 source build/envbuild.sh lunch xxx make 2.单独编译模块 2.1 去Android.bp 中找模块名 比如我想编译system/core/fastboot,那么我就去找这个路径下的Android.bp/ Android.mk Android.bp 中找每个模块的那么就行 然后直接make这个name make fastboot_…

通过【Stable-Diffusion WEBUI】复刻属于你的女神:再谈模型与参数

文章目录 (零)前言(一)复刻优秀的作品(1.1)模型(1.1.1)Model Hash (1.2)提示词(1.2.1)反推提示词 (1.3)参数 &…

GaussDB数据库基础函数介绍-上

目录 一、函数在数据库中的作用 二、GaussDB常用基础函数介绍与示例 1、数字操作函数 2、时间和日期处理函数 3、类型转换函数 4、数组函数 5、范围函数 6、窗口函数 7、聚集函数 8、安全函数 9、系统信息函数 10、动态脱敏函数. Tip:由于篇幅缘故&…

shell脚本的条件判断式

文章目录 shell脚本的条件判断式利用 if...then单层、简单条件判断式多重、复杂条件判断式例题1例题2 利用case...esac判断例题1 利用function功能例题1 shell脚本的条件判断式 很多时候我们必须要根据某些数来判断程序该如何举例来说,我们在之前的练习中让用户输入…

jsp网上拍卖管理系统统Myeclipse开发mysql数据库web结构jsp编程计算机网页项目

一、源码特点 jsp网上拍卖管理系统是一套完善的java web信息管理系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发,数据库为Mysql5.0&a…

AWS Lambda - 第一部分

Hello大家好,我们今天开始讨论AWS Lambda的内容。 SAP认证考试会涉及到很多Lambda的内容,想要通过认证考试虽然不一定非要精通开发,但需要知道Lambda的一些功能和特性、适用场景以及Lambda是如何工作的。 我们开始吧! Lambda与…

数据结构刷题(三十):96不同的二叉搜索树、01背包问题理论、416分割等和子集

一、96. 不同的二叉搜索树 1.这个题比较难想递推公式, dp[3],就是元素1为头结点搜索树的数量 元素2为头结点BFS的数量 元素3为头结点BFS的数量 元素1为头结点搜索树的数量 右子树有2个元素的搜索树数量 * 左子树有0个元素的搜索树数量 元素2为头结…

AWS Lambda - 第二部分

Hello大家好,我们今天继续讨论AWS Lambda的内容。 Lambda的网络 首先,我们来讨论一下Lambda的网络,联网相关的内容。 在部署Lambda时,在默认情况下,Lambda函数是部署和运行在AWS的一个安全的VPC中,是在您…

“大运”有我丨智安网络护航大运,荣获成都市公安局感谢信!

近日,深圳市智安网络有限公司四川分公司(以下简称“智安网络”)荣幸受邀参与第31届世界大学生夏季运动会网络安全检查工作,对中和体育中心场馆安全漏洞检测进行现场技术支撑。 智安网络对此次网络安全检查工作高度重视&#xff0…

PySpark基础入门(2):RDD及其常用算子

更好的阅读体验:PySpark基础入门(2):RDD及其常用算子 - 掘金 (juejin.cn) 目录 RDD简介 RDD Coding RDD简介 RDD(Resilient Distributed Dataset),是一个弹性分布式数据集,是Sp…

带你快速入门光模块行业

一、行业介绍 光纤通信(简称光通信)是利用光导纤维传输光波信号的一种通信方式,于上世纪六七十年代由华裔科学家高锟博士等人率先提出。 光通信是以激光作为信息载体,以光纤作为传输媒介的通信方式,现已取代电通信成…

if __name__ == “__main__“: 理解

if __name__ "__main__": 是 Python 中常用的一种条件判断语句,主要作用是在当前模块作为程序入口时执行一些特定的代码,而在被其它模块引入时不执行这些特定的代码。 具体来说,当一个 Python 模块被导入时,Python 解…

关注度拉满,RSAC 2023 热门安全工具速览

RSAConference2023于当地时间4月24日在旧金山正式拉开帷幕。自上届RSAC以来,网络安全行业发生了巨大的变化,尤其是以OpenAI聊天机器人为代表的内容生成型AI的兴起,对网络防御和攻击的影响比以往任何时候都更加明显。 今年,与RSAC相…

数据结构之第十章、Java对象的比较

目录 一、PriorityQueue(堆)中插入对象 二、元素的比较 2.1基本类型的比较 2.2对象比较的问题 三、对象的比较 3.1覆写基类的equals 3.2基于Comparble接口类的比较 3.3基于比较器比较 3.4三种方式对比 3.5代码实现 四、集合框架中PriorityQu…

大型医院影像PACS系统三维重建技术(获取数据、预处理、配准、重建和可视化)

PACS(Picture Archiving and Communication System)系统作为医学图像的存储和传输平台,为医生和患者提供了便捷高效的诊疗服务支持。近年来,三维重建技术在PACS系统中的应用越来越广泛。 一、三维重建技术的基本原理 在PACS系统…

JS 中的 performance,测量web应用性能

文章目录 属性和方法performance.memory 内存performance.navigation 页面的来源信息performance.timing 时间消耗相关时间计算Performance.mark()performance.now() Web Performance API 允许网页访问某些函数来测量网页和 Web 应用程序的性能 performance 包含如下属性和方法…

Linux基础IO【软硬链接与动静态库】

✨个人主页: 北 海 🎉所属专栏: Linux学习之旅 🎃操作环境: CentOS 7.6 阿里云远程服务器 文章目录 🌇前言🏙️正文1、软硬链接1.1、基本认知1.2、实现原理1.3、应用场景1.4、取消链接1.5、ACM时…

JavaWeb ( 一 ) HTTP协议

1.http协议 1.0.Web Web指的是World Wide Web,也称为万维网,是一种基于互联网的信息系统,由全球数百万个网站组成。它允许用户通过使用网页浏览器访问和交互信息,例如阅读新闻、购物、发送和接收电子邮件、社交媒体等。 Web使用…

解密.[support2022@cock.li].faust后缀勒索病毒加密的文件:拯救您的企业数据的完整指南!

引言: 您的企业数据是您业务的核心。但是,当.[support2022cock.li].faust后缀勒索病毒突袭您的系统时,您的数据将遭受沉重打击。这种恶意软件利用高级加密算法,将您的文件锁定在无法访问的状态。在这篇详细的指南中,9…