streamlit+pywebview, pure python to write desktop applications in the form of front-end and back-end

1、VSCode

VSCode
VSCode Extension: Python

2. Configure the PowerShell execution policy

Run PowerShell as an administrator, run Set-ExecutionPolicy RemoteSigned, and enter Y, press Enter to confirm

3. Configure the Python environment

  1. Only install Python: Huawei mirror , Ali mirror , newbe , Python official website ftp address , Python official website Chinese page
  2. Python embedded version: Python3.11.3 download page , Python3.11.3 embedded version download direct link , embedded compressed packages of each image
  3. Virtual environment or version management: venv , virtualenv , virtualenvwrapper , poetry , conda , Anaconda , Miniconda Tsinghua mirror , pyenv-win's Github repository , pyenv-virtualenv , pipenv

In streamlit's getting started documentation , the supported Python versions are 3.7 - 3.11

This article uses embedded Python3.11.3 64-bit python-3.11.3-embed-amd64.zip
to decompress it into python-3.11.3-embed-amd64a folder and rename itpython3.11.3-e

4. Adjust project structure

Create a new folder histreamlitand python3.11.3-eput it histreamlitin the folder
Path:histreamlit\python3.11.3-e

Create a new subfolder histreamlit, path: histreamlit\histreamlit
add an ico format picture, path:histreamlit\2530812_crest_crown_general_item_jwellery_icon.ico
insert image description here

5. Continue to configure the Python environment

.\python3.11.3-e\pip.ini, create a new file with the following content

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

Download get-pip.py , put it in python3.11.3-ethe folder
and run.\python3.11.3-e\python.exe .\python3.11.3-e\get-pip.py

Edit histreamlit\python3.11.3-e\python311._pththe file and #import sitechange toimport site

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

6. Install streamlit

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

7. Run the hello project that comes with streamlit

.\python3.11.3-e\Scripts\streamlit.exe hello
insert image description here
Automatically start the browser display interface
insert image description here
Ctrl+Cto stop running (response is extremely slow, it is better to close the command line window and open another one)

8. Copy the official demo

insert image description here
Create a new file histreamlit\histreamlit\main.py
insert image description here
Open the folder with VSCode histreamlit, select the interpreter in the lower right corner, click Enter interpreter path…, click Find…, select .\python3.11.3-e\python.exe, clickSelect Interpreter

Edit the file histreamlit\histreamlit\main.py(copy the official 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. Run

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

10. Run silently without starting the browser

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

11. Install PyWebview

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

12. Create a new file 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. Run streamlit+pywebview

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

14. Run streamlit+pywebview (bat script)

create a new filehistreamlit\histreamlit\start.bat

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

Double click start.batto run

15. Write vbs, start without displaying the console

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表示显示窗口

The only difference is that one parameter uses 1, and the other uses 0.
Double-click the vbs script to run

16. Convert vbs to exe

Note: The vbs with the words gb18030 in the previous screenshot is just the text encoding is gb18030, because the software used to convert vbs to exe does not know utf8, and the text in the comment will be garbled


Take start_gb18030.vbstransfer start.exeas an example ,
insert image description here
check 图标it, select the ico file
EXE格式, and change it to 32-bit | Windows (invisible), (here, the invisible is the invisible of vbs, not bat, and the window of python is invisible) Check it and
click 启用 UPX 压缩
on the toolbar 转换(the round bottom gear icon) , the file name is start.exesaved, and the software will generate an exe file
insert image description here

17. The final effect

Running start.exe
insert image description here
Close the window cmd of pywebview will be displayed for a while Closing window..., and then disappear.
insert image description here
Running start_noconsole.exeis the same, but there is no console window, more like a desktop application

18. How to distribute

Is there anything that can be distributed, the folder can be sent to others to run the exe, and if you want to distribute it, you still want to encrypt it, use the server, it must be encrypted



7. (Failure) Refer to the topic and make a desktop application

(Reason for failure: npm run dump histreamlit numpyrunning forever, stagnant output)
Streamlit - Issue #1370
@stlite/desktop - README.md

8. (Failure) Install nvm

Visit the download address to download and install nvm:
Baidu cloud sharing
official website direct installation link
nvm's github release interface download nvm-setup.exe
GitCode mirror download nvm-setup.exe (login to get the download link, the download link is still from Github, the only function is to select version soon)

9. (Failure) configure nvm

nvm install ltsInstall the latest version of Node.js, this article is to 18.16.0
nvm use ltsenable this version
to run cmd /c "nvm -v && node -v && npm -v", the normal output version number indicates that the installation is complete

10. (Failure) configure npm mirror

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

11. (Failed) Prepare to use stlite

histreamlit-eand histreamlitthe two folders should be at the same level, they are independent

md histreamlit-e
cd .\histreamlit-e\
npm init -y
code .
Edit the file .\histreamlit-e\package.jsonand change it to the following

{
    
    
  "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"
  }
}

Visit the following npm package, check the version and modify package.json
insert image description here
@stlite/desktop - npm
cross-env - npm
electron - npm
electron-builder - npm
For example, the screenshot below:
insert image description here

12. (Failed) install dependencies

in histreamlit-ethe directory
runcmd /c "set ELECTRON_MIRROR=https://npmmirror.com/mirrors/electron/&& npm install"

Prompt high-risk: 6 high severity vulnerabilities
run cmd /c "npm audit fix --force --registry=https://registry.npmjs.org"to solve high-risk

13. (Failure) Write the content of hisstreamlit into hisstreamlit-e

Create a new file .\histreamlit-e\histreamlit\streamlit_app.pywith the .\histreamlit\histreamlit\main.pysame content as

14. (failed) run

In histreamlit-ethe directory,
npm run dump histreamlit numpy
it has been running and cannot be completed, there is no CPU or disk usage, maybe it is downloading something but there is no timeout function.





Please add a picture description

Guess you like

Origin blog.csdn.net/qq_39124701/article/details/130383450