Ver código fonte

激光测量v1

wei_lai 6 meses atrás
pai
commit
0d551f5eb7
3 arquivos alterados com 291 adições e 0 exclusões
  1. 41 0
      orginal_plot.py
  2. 247 0
      readme1.md
  3. 3 0
      test.py

+ 41 - 0
orginal_plot.py

@@ -0,0 +1,41 @@
+import os
+import pandas as pd
+import seaborn as sns
+import matplotlib.pyplot as plt
+from matplotlib.ticker import MaxNLocator
+import warnings
+
+warnings.filterwarnings("ignore", category=FutureWarning)  # 忽略特定警告
+plt.rcParams['font.sans-serif'] = ['SimHei']  # 使用黑体
+plt.rcParams['axes.unicode_minus'] = False  # 解决保存图像是负号'-'显示为方块的问题
+
+# 指定文件夹路径
+folder_path = r'C:/Users/laiwe/Desktop/风电/激光测量/测试数据/20250513/'
+
+# 遍历文件夹中的所有CSV文件
+for filename in os.listdir(folder_path):
+    if filename.endswith('.csv'):
+        csv_path = os.path.join(folder_path, filename)
+        # 读取第2、4、9列的数据
+        data = pd.read_csv(csv_path, usecols=[1, 3, 8], header=None, engine='c')
+
+        # 绘制原始数据图
+        data.columns = ['time', 'distance1', 'distance2']
+        plt.figure(figsize=(300, 150))
+        sns.scatterplot(data=data, x='time', y='distance1', s=50, color='green')
+        sns.scatterplot(data=data, x='time', y='distance2', s=50, color='red')
+        abxy = plt.gca()  # 获取当前坐标轴对象
+        plt.grid(linewidth=2)  # 设置网格线宽度为2
+        abxy.xaxis.set_major_locator(MaxNLocator(nbins=100))  # 设置x轴主刻度的最大数量为10
+        plt.xlabel('时间', fontsize=16, fontweight='bold')  # 添加x轴标签
+        plt.ylabel('距离(m)', fontsize=16, fontweight='bold')  # 添加y轴标签
+        abxy.tick_params(axis='x', labelsize=14, labelcolor='black', width=2)  # 设置x轴刻度标签
+        abxy.tick_params(axis='y', labelsize=14, labelcolor='black', width=2)  # 设置y轴刻度标签
+
+        # 生成图像文件名
+        image_filename = os.path.splitext(filename)[0] + '.png'
+        image_path = os.path.join(folder_path, image_filename)
+
+        # 保存图像
+        plt.savefig(image_path, dpi=100, pil_kwargs={"icc_profile": False})
+        plt.close()

+ 247 - 0
readme1.md

@@ -0,0 +1,247 @@
+<!--
+ * @Author: your name
+ * @Date: 2025-03-11 14:21:26
+ * @LastEditTime: 2025-03-11 14:21:29
+ * @LastEditors: milo-MacBook-Pro.local
+ * @Description: In User Settings Edit
+ * @FilePath: /exetest/readme1.md
+-->
+
+### **🎯 目标:用 Python 作为 EXE,暴露 /api/a1 和 /api/a2 两个 API**
+
+> **思路**:Electron **通过 `child_process.execFile` 运行 Python EXE**,Python **解析 API 名称和参数**,执行相应逻辑并返回 JSON 结果。
+
+---
+
+## **🔹 1️⃣ Python 代码**
+
+创建 `data_analyse.py`,用于处理 API 请求。
+
+```python
+import sys
+import json
+
+# **定义 API 处理函数**
+def api_a1():
+    return {"message": "Hello from API A1"}
+
+def api_a2(data):
+    return {"received": data}
+
+if __name__ == "__main__":
+    # **🔹 解析命令行参数**
+    if len(sys.argv) < 2:
+        print(json.dumps({"error": "No API specified"}))
+        sys.exit(1)
+
+    api_name = sys.argv[1]  # 第一个参数是 API 名称
+
+    if api_name == "a1":
+        result = api_a1()
+    elif api_name == "a2":
+        if len(sys.argv) < 3:
+            print(json.dumps({"error": "No data for A2"}))
+            sys.exit(1)
+        data = json.loads(sys.argv[2])  # 解析 JSON 参数
+        result = api_a2(data)
+    else:
+        result = {"error": "Unknown API"}
+
+    print(json.dumps(result))  # **返回 JSON 格式数据**
+```
+
+---
+
+## **🔹 2️⃣ 将 Python 代码打包成 EXE**
+
+### **📌 安装 `pyinstaller`**
+
+```bash
+pip install pyinstaller
+```
+
+### **📌 生成 EXE**
+
+```bash
+pyinstaller --onefile data_analyse.py
+```
+
+成功后,你会在 `dist/` 目录下找到 `data_analyse.exe`。
+
+> **📌 复制 EXE 文件到 Electron 项目**
+> 将 `dist/data_analyse.exe` 复制到 `../severs/dist/data_analyse/`
+
+---
+
+## **🔹 3️⃣ Electron 主进程调用 Python EXE**
+
+修改 `main.mjs`,让 Electron **监听渲染进程的请求** 并运行 Python EXE。
+
+```javascript
+import { app, BrowserWindow, ipcMain } from "electron";
+import { fileURLToPath } from "url";
+import path from "path";
+import { execFile } from "child_process";
+
+process.env["ELECTRON_DISABLE_SECURITY_WARNINGS"] = "true";
+
+const __filename = fileURLToPath(import.meta.url);
+const __dirname = path.dirname(__filename);
+
+let mainWindow = null;
+
+function createWindow() {
+  mainWindow = new BrowserWindow({
+    width: 1000,
+    height: 800,
+    webPreferences: {
+      preload: path.join(__dirname, "./preload.mjs"),
+      contextIsolation: true,
+      nodeIntegration: false,
+      allowRunningInsecureContent: false,
+    },
+  });
+
+  if (process.env.NODE_ENV === "development") {
+    mainWindow.loadURL("http://localhost:5173/home");
+    mainWindow.webContents.openDevTools();
+  } else {
+    mainWindow.loadFile(path.join(__dirname, "../dist/index.html"));
+    mainWindow.webContents.openDevTools();
+  }
+
+  mainWindow.on("closed", () => {
+    mainWindow = null;
+  });
+}
+
+// **🔹 监听渲染进程的请求,执行 Python EXE**
+ipcMain.handle("run-python-exe", async (event, apiName, params = {}) => {
+  return new Promise((resolve, reject) => {
+    const pythonExePath = path.join(
+      __dirname,
+      "../severs/dist/data_analyse/data_analyse.exe"
+    ); // **Python EXE 路径**
+
+    // **传递 API 名称和参数**
+    const args = [apiName, JSON.stringify(params)];
+
+    const child = execFile(pythonExePath, args, (error, stdout, stderr) => {
+      if (error) {
+        console.error("❌ Python EXE 运行失败:", error);
+        reject(`Error: ${error.message}`);
+        return;
+      }
+      if (stderr) {
+        console.warn("⚠️ Python EXE 输出警告:", stderr);
+      }
+
+      try {
+        resolve(JSON.parse(stdout)); // **解析 JSON 返回给前端**
+      } catch (parseError) {
+        reject("Invalid JSON response from Python");
+      }
+    });
+  });
+});
+
+app.whenReady().then(createWindow);
+
+app.on("window-all-closed", () => {
+  if (process.platform !== "darwin") app.quit();
+});
+
+app.on("activate", () => {
+  if (BrowserWindow.getAllWindows().length === 0) createWindow();
+});
+
+export { createWindow };
+```
+
+---
+
+## **🔹 4️⃣ 渲染进程(前端)调用 Python**
+
+修改 `preload.mjs`,暴露 API 让前端调用。
+
+```javascript
+import { contextBridge, ipcRenderer } from "electron";
+
+contextBridge.exposeInMainWorld("electronAPI", {
+  callPythonAPI: (apiName, params) =>
+    ipcRenderer.invoke("run-python-exe", apiName, params),
+});
+```
+
+---
+
+## **🔹 5️⃣ 前端(Vue / React / HTML)调用 Python**
+
+```javascript
+async function fetchA1() {
+  try {
+    const result = await window.electronAPI.callPythonAPI("a1");
+    console.log("A1 API 响应:", result);
+  } catch (error) {
+    console.error("A1 API 失败:", error);
+  }
+}
+
+async function fetchA2() {
+  try {
+    const result = await window.electronAPI.callPythonAPI("a2", {
+      name: "Alice",
+    });
+    console.log("A2 API 响应:", result);
+  } catch (error) {
+    console.error("A2 API 失败:", error);
+  }
+}
+
+fetchA1();
+fetchA2();
+```
+
+---
+
+## **✅ 运行步骤**
+
+### **1️⃣ 先编译 Python 为 EXE**
+
+```bash
+pyinstaller --onefile data_analyse.py
+```
+
+然后把 `dist/data_analyse.exe` 复制到 `../severs/dist/data_analyse/`
+
+---
+
+### **2️⃣ 运行 Electron**
+
+```bash
+npm run electron:dev
+```
+
+---
+
+## **🚀 运行结果**
+
+- **调用 `callPythonAPI("a1")`**
+  ```json
+  { "message": "Hello from API A1" }
+  ```
+- **调用 `callPythonAPI("a2", { "name": "Alice" })`**
+  ```json
+  { "received": { "name": "Alice" } }
+  ```
+
+---
+
+## **🎯 总结**
+
+1. **Python 解析 API 名称和参数**,执行相应逻辑,并返回 JSON 结果。
+2. **Electron 主进程监听前端的调用**,用 `execFile` 运行 Python EXE,并传递 API 名称和参数。
+3. **渲染进程(前端)使用 `window.electronAPI.callPythonAPI()`** 触发 Python 调用。
+4. **Electron 解析 Python 输出,并返回给前端**。
+
+这样你就成功在 **Electron 中调用 Python EXE,并通过 JSON 格式返回 API 数据**! 🚀🚀🚀

+ 3 - 0
test.py

@@ -0,0 +1,3 @@
+
+a = list(range(1, 11, 8))
+print(a)