備忘錄_20160105(定位)
修改
回首頁
程式 2025-04-17 00:48:30 1744822110 100
python 混合 fastapi 與 tkinter 使用
python 混合 fastapi 與 tkinter 使用
這個程式再修整修整,就可以做出 SaveAs 和 Save(不用再詢問) 了
●save.py
# api
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
import uvicorn
from pydantic import BaseModel # 為了 post
# gui
import tkinter as tk
from tkinter import filedialog
# 協同合作
import threading
import queue
import time
import asyncio
oQueue_to_gui = queue.Queue()
oQueue_to_api = queue.Queue()
oStopEvent=threading.Event()
class CData(BaseModel):
strData: str
oMyFastApi = FastAPI()
oMyFastApi.add_middleware(CORSMiddleware, allow_origins=["*"], allow_methods=["*"], allow_headers=["*"]) # 為了 CORS
@oMyFastApi.get("/stop")
def func_stop():
global oUvicornServer
oStopEvent.set()
oUvicornServer.should_exit=True
return { "訊息": "已送出停止訊息。" }
@oMyFastApi.post("/save")
def func_save(oData: CData):
oQueue_to_gui.put(oData)
while True:
time.sleep(0.1)
if not oQueue_to_api.empty():
strFilename=oQueue_to_api.get_nowait()
break
return { "strFilename": strFilename }
async def run_api():
oConfig=uvicorn.Config(oMyFastApi, host="0.0.0.0", port=8000)
global oUvicornServer
oUvicornServer=uvicorn.Server(oConfig)
await oUvicornServer.serve()
def run_gui():
while not oStopEvent.is_set():
time.sleep(0.1)
if not oQueue_to_gui.empty():
oData=oQueue_to_gui.get_nowait()
oRoot=tk.Tk()
strFilename=filedialog.asksaveasfilename(
title="儲存檔案",
defaultextension=".txt",
filetypes=[("Text files", "*.txt"), ("All files", "*.*")]
)
oQueue_to_api.put(strFilename)
if strFilename!="":
with open(strFilename, "w", encoding="utf-8", newline='') as oFile:
oFile.write(oData.strData)
oRoot.destroy() # 用完關掉 root 視窗
api_thread = threading.Thread(target=lambda: asyncio.run(run_api()), daemon=True)
api_thread.start()
gui_thread = threading.Thread(target=run_gui, daemon=True)
gui_thread.start()
api_thread.join()
gui_thread.join()
●呼叫的 javascript 為
fetch(
'http://127.0.0.1:8000/save',
{
method: "POST",
headers: {"Content-Type": "application/json"},
body: JSON.stringify({ strData: "耶,可以存檔了!\r\n第二行!"})
}
)
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error(err));