electron 官网速通

news2024/9/29 1:27:31

前言:参考Electron 中文网。

核心知识点:有哪些进程进程之间的通信electron API 分类及怎么调用

一、快速开始

1. 新建一个 my-electron 的文件夹。

2. 运行 npm init 创建 package.json 文件。

3. 填写 author 和 description 字段,应用打包必须。

4. 运行 npm install --save-dev electron,安装依赖。

安装报错时,可参考安装 electron 报错解决

5. 安装 Electron Forge 依赖,并使用其 import 命令来设置 Forge 的脚手架,用来打包应用。

npm install --save-dev @electron-forge/cli

npx electron-forge import

6. 修改 package.json 的 scripts 对象

使用 nodemon 启动命令,可以动态更新 main.js 的修改,不用重复启服务。

{

  "name": "electron-demo",

  "version": "1.0.0",

  "description": "this is a demo",

  "main": "main.js",

  "scripts": {

    "start": "nodemon --watch main.js --exec npm run build",

    "build": "electron-forge start",

    "package": "electron-forge package",

    "make": "electron-forge make",

    "publish": "electron-forge publish"

  },

  "keywords": [],

  "author": "yqcoder",

  "license": "ISC",

  "devDependencies": {

    "@electron-forge/cli": "^7.4.0",

    "@electron-forge/maker-deb": "^7.4.0",

    "@electron-forge/maker-rpm": "^7.4.0",

    "@electron-forge/maker-squirrel": "^7.4.0",

    "@electron-forge/maker-zip": "^7.4.0",

    "@electron-forge/plugin-auto-unpack-natives": "^7.4.0",

    "@electron-forge/plugin-fuses": "^7.4.0",

    "@electron/fuses": "^1.8.0",

    "electron": "^31.3.1"

  },

  "dependencies": {

    "electron-squirrel-startup": "^1.0.1"

  }

}

7. 根目录创建 main.js 文件

const { app, BrowserWindow } = require("electron");

const path = require("node:path");



const createWindow = () => {

  const mainWindow = new BrowserWindow({

    width: 800,

    height: 600,

    webPreferences: {

      preload: path.join(__dirname, "preload.js"),

    },

  });



  mainWindow.loadFile("index.html");

};

app.whenReady().then(() => {

  createWindow();



  app.on("activate", () => {

    if (BrowserWindow.getAllWindows().length === 0) createWindow();

  });

});



app.on("window-all-closed", () => {

  if (process.platform !== "darwin") app.quit();

});

8. 根目录创建 index.html 文件

<!DOCTYPE html>

<html lang="en">

  <head>

    <meta charset="UTF-8" />

    <!-- https://web.nodejs.cn/en-US/docs/Web/HTTP/CSP -->

    <meta

      http-equiv="Content-Security-Policy"

      content="default-src 'self'; script-src 'self'"

    />

    <title>Hello World!</title>

  </head>

  <body>

    <h1>Hello World!</h1>

    We are using Node.js <span id="node-version"></span>, Chromium

    <span id="chrome-version"></span>, and Electron

    <span id="electron-version"></span>.

    <script src="./renderer.js"></script>

  </body>

</html>

9. 根目录创建 preload.js 文件

window.addEventListener("DOMContentLoaded", () => {

  const replaceText = (selector, text) => {

    const element = document.getElementById(selector);

    if (element) element.innerText = text;

  };



  for (const dependency of ["chrome", "node", "electron"]) {

    replaceText(`${dependency}-version`, process.versions[dependency]);

  }

});

10. 运行项目

npm run start

11. 项目打包

npm run make

二、页面

BrowserWindow API 用于创建和管理应用窗口

1. 页面载入

每个窗口内容都是一个页面,页面可以是本地 HTML 或远程网址。

1.1 创建页面

在根目录中创建 index.html 网页:

<!DOCTYPE html>

<html>

  <head>

    <meta charset="UTF-8" />

    <meta

      http-equiv="Content-Security-Policy"

      content="default-src 'self'; script-src 'self'"

    />

    <meta

      http-equiv="X-Content-Security-Policy"

      content="default-src 'self'; script-src 'self'"

    />

    <title>Hello from Electron renderer!</title>

  </head>

  <body>

    <h1>Hello from Electron renderer!</h1>

    <p>👋</p>

  </body>

</html>

1.2 实例化窗口加载页面

构建 createWindow() 函数,实例化窗口,并将网页通过 loadFile 方法加载进去。

const createWindow = () => {

  const win = new BrowserWindow({

    width: 800,

    height: 600,

  });



  win.loadFile("index.html");

};

1.3 应用准备就绪后加载窗口

app API 控制应用的事件生命周期。

app.whenReady().then(() => {

  createWindow();

});

所有窗口关闭后退出应用(Windows 和 Linux)

app.on("window-all-closed", () => {

  if (process.platform !== "darwin") app.quit();

});

如果没有打开窗口,则打开一个窗口 (macOS)

app.whenReady().then(() => {

  createWindow();



  app.on("activate", () => {

    if (BrowserWindow.getAllWindows().length === 0) createWindow();

  });

});

三、进程间通信

1. 预加载脚本

通过预加载脚本,可以将主进程属性暴露给渲染进程。

创建 preload.js 预加载脚本将 process.versions 对象的选定属性公开给渲染器进程。

// preload.js

const { contextBridge } = require("electron");



contextBridge.exposeInMainWorld("versions", {

  node: () => process.versions.node,

  chrome: () => process.versions.chrome,

  electron: () => process.versions.electron,

});

将脚本附加到渲染器进程,通过 webPreferences.preload 选项

// main.js

const { app, BrowserWindow } = require("electron");

const path = require("node:path");



const createWindow = () => {

  const win = new BrowserWindow({

    width: 800,

    height: 600,

    webPreferences: {

      preload: path.join(__dirname, "preload.js"),

    },

  });



  win.loadFile("index.html");

};



app.whenReady().then(() => {

  createWindow();

});

在渲染进程使用,创建 renderer.js,载入到页面

// renderer.js

const information = document.getElementById("info");

information.innerText = `This app is using Chrome (v${versions.chrome()}), Node.js (v${versions.node()}), and Electron (v${versions.electron()})`;
<!DOCTYPE html>

<html>

  <head>

    <meta charset="UTF-8" />

    <meta

      http-equiv="Content-Security-Policy"

      content="default-src 'self'; script-src 'self'"

    />

    <meta

      http-equiv="X-Content-Security-Policy"

      content="default-src 'self'; script-src 'self'"

    />

    <title>Hello from Electron renderer!</title>

  </head>

  <body>

    <h1>Hello from Electron renderer!</h1>

    <p>👋</p>

    <p id="info"></p>

  </body>

  <script src="./renderer.js"></script>

</html>

2. ipcMain 和 ipcRenderer

ipcRenderer.on(channel, listener):监听 channel,当有新消息到达时,listener 将与 listener(event, args...) 一起调用。

ipcRenderer.send(channel, ...args):通过 channel 向主进程发送异步消息以及参数。

ipcRenderer.invoke(channel, ...args):通过 channel 向主进程发送消息并异步期待结果。

ipcMain.on(channel, listener):监听 channel,当有新消息到达时,listener 将与 listener(event, args...) :一起调用。

ipcMain.handle(channel, listener):添加 invokeable IPC 的处理程序。每当渲染器调用 ipcRenderer.invoke(channel, ...args) :时就会调用此处理程序。

2.1 渲染器到主进程(单向)

使用 ipcRenderer.send 与 ipcMain.on 配对完成。

在 main.js 中监听 set-title 事件

// main.js

const { app, BrowserWindow, ipcMain } = require("electron/main");

const path = require("node:path");



function createWindow() {

  const mainWindow = new BrowserWindow({

    webPreferences: {

      preload: path.join(__dirname, "preload.js"),

    },

  });



  ipcMain.on("set-title", (event, title) => {

    const webContents = event.sender;

    const win = BrowserWindow.fromWebContents(webContents);

    win.setTitle(title);

  });



  mainWindow.loadFile("index.html");

}



app.whenReady().then(() => {

  createWindow();



  app.on("activate", function () {

    if (BrowserWindow.getAllWindows().length === 0) createWindow();

  });

});



app.on("window-all-closed", function () {

  if (process.platform !== "darwin") app.quit();

});

预加载脚本定义渲染进程触发 set-title 事件方式

// preload.js

const { contextBridge, ipcRenderer } = require("electron/renderer");



contextBridge.exposeInMainWorld("electronAPI", {

  setTitle: (title) => ipcRenderer.send("set-title", title),

});

渲染进程触发 set-title 事件

// renderer.js

const setButton = document.getElementById("btn");

const titleInput = document.getElementById("title");

setButton.addEventListener("click", () => {

  const title = titleInput.value;

  window.electronAPI.setTitle(title);

});
<!-- index.html -->

<!DOCTYPE html>

<html>

  <head>

    <meta charset="UTF-8" />

    <!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->

    <meta

      http-equiv="Content-Security-Policy"

      content="default-src 'self'; script-src 'self'"

    />

    <title>Hello World!</title>

  </head>

  <body>

    Title: <input id="title" />

    <button id="btn" type="button">Set</button>

    <script src="./renderer.js"></script>

  </body>

</html>

2.2 渲染器到主进程(双向)

使用 ipcRenderer.invoke 与 ipcMain.handle 配对完成。

// preload.js

const { contextBridge, ipcRenderer } = require("electron/renderer");



contextBridge.exposeInMainWorld("electronAPI", {

  openFile: () => ipcRenderer.invoke("dialog:openFile"),

});
// main.js

const { app, BrowserWindow, ipcMain, dialog } = require("electron/main");

const path = require("node:path");



async function handleFileOpen() {

  const { canceled, filePaths } = await dialog.showOpenDialog();

  if (!canceled) {

    return filePaths[0];

  }

}

function createWindow() {

  const mainWindow = new BrowserWindow({

    webPreferences: {

      preload: path.join(__dirname, "preload.js"),

    },

  });

  mainWindow.loadFile("index.html");

}

app.whenReady().then(() => {

  ipcMain.handle("dialog:openFile", handleFileOpen);

  createWindow();

  app.on("activate", function () {

    if (BrowserWindow.getAllWindows().length === 0) createWindow();

  });

});



app.on("window-all-closed", function () {

  if (process.platform !== "darwin") app.quit();

});
// renderer.js

const btn = document.getElementById("btn");

const filePathElement = document.getElementById("filePath");



btn.addEventListener("click", async () => {

  const filePath = await window.electronAPI.openFile();

  filePathElement.innerText = filePath;

});
<!DOCTYPE html>

<html>

  <head>

    <meta charset="UTF-8" />

    <!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->

    <meta

      http-equiv="Content-Security-Policy"

      content="default-src 'self'; script-src 'self'"

    />

    <title>Dialog</title>

  </head>

  <body>

    <button type="button" id="btn">Open a File</button>

    File path: <strong id="filePath"></strong>

    <script src="./renderer.js"></script>

  </body>

</html>

2.3 主进程到渲染器

// preload.js

const { contextBridge, ipcRenderer } = require("electron/renderer");



contextBridge.exposeInMainWorld("electronAPI", {

  onUpdateCounter: (callback) =>

    ipcRenderer.on("update-counter", (_event, value) => callback(value)),

  counterValue: (value) => ipcRenderer.send("counter-value", value),

});
// main.js

const { app, BrowserWindow, Menu, ipcMain } = require("electron/main");

const path = require("node:path");



function createWindow() {

  const mainWindow = new BrowserWindow({

    webPreferences: {

      preload: path.join(__dirname, "preload.js"),

    },

  });

  const menu = Menu.buildFromTemplate([

    {

      label: app.name,

      submenu: [

        {

          click: () => mainWindow.webContents.send("update-counter", 1),

          label: "Increment",

        },

        {

          click: () => mainWindow.webContents.send("update-counter", -1),

          label: "Decrement",

        },

      ],

    },

  ]);



  Menu.setApplicationMenu(menu);

  mainWindow.loadFile("index.html");



  // Open the DevTools.

  mainWindow.webContents.openDevTools();

}



app.whenReady().then(() => {

  ipcMain.on("counter-value", (_event, value) => {

    console.log(value); // will print value to Node console

  });

  createWindow();



  app.on("activate", function () {

    if (BrowserWindow.getAllWindows().length === 0) createWindow();

  });

});



app.on("window-all-closed", function () {

  if (process.platform !== "darwin") app.quit();

});
// renderer.js

const counter = document.getElementById("counter");



window.electronAPI.onUpdateCounter((value) => {

  const oldValue = Number(counter.innerText);

  const newValue = oldValue + value;

  counter.innerText = newValue.toString();

  window.electronAPI.counterValue(newValue);

});
<!DOCTYPE html>

<html>

  <head>

    <meta charset="UTF-8" />

    <!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->

    <meta

      http-equiv="Content-Security-Policy"

      content="default-src 'self'; script-src 'self'"

    />

    <title>Menu Counter</title>

  </head>

  <body>

    Current value: <strong id="counter">0</strong>

    <script src="./renderer.js"></script>

  </body>

</html>

2.4 渲染器到渲染器

没有直接的方法可以使用 ipcMain 和 ipcRenderer 在渲染器进程之间发送消息。为了实现这一目标,你有两种选择:

1. 使用主进程作为渲染器之间的消息代理。这将涉及从一个渲染器向主进程发送消息,主进程会将消息转发到另一个渲染器。

2. 将 MessagePort 从主进程传递到两个渲染器。这将允许在初始设置后渲染器之间进行直接通信。

四、API 文档

本章只做概览,详情参考[Electron API 文档](https://electron.nodejs.cn/docs/latest/api/app)

1. 主进程模块

1.1 app

控制应用的事件生命周期。内置事件、方法、属性。

1.1.1 whenReady()

当 Electron 完成初始化时发出一次。

// main.js
const { app } = require("electron")

app.whenReady().then(() => {
  // 创建窗口
});

1.2 autoUpdater

使应用能够自动更新。内置事件、方法。

1.3 BaseWindow

创建和控制窗口。内置实例事件、静态方法、实例属性、实例方法。

1.4 BrowserWindow

创建和控制浏览器窗口。内置实例事件、静态方法、实例属性、实例方法。

1.5 clipboard

在系统剪贴板上执行复制和粘贴操作。内置方法。

1.6 contentTracing

从 Chromium 收集跟踪数据以查找性能瓶颈和缓慢的操作。内置方法。

1.7 crashReporter

将崩溃报告提交到远程服务器。内置方法。

1.8 desktopCapturer

访问有关可用于使用 navigator.mediaDevices.getUserMedia API 从桌面捕获音频和视频的媒体源的信息。内置方法。

1.9 dialog

显示用于打开和保存文件、警报等的原生系统对话框。内置方法。

1.10 globalShortcut

当应用没有键盘焦点时检测键盘事件。内置方法。

1.11 inAppPurchase

Mac App Store 上的应用内购买。内置事件、方法。

1.12 ipcMain

从主进程到渲染器进程异步通信。内置方法。

1.13 Menu

创建原生应用菜单和上下文菜单。内置实例事件、静态方法、实例属性、实例方法。

1.13.1 buildFromTemplate

返回 Menu

const { Menu } = require("electron");

let menuTemp = [
  {
    label: "文件",
    click() {
      // TODO
    },
    submenu: [
      {
        label: "打开",
      },
      {
        type: "separator", // 横线
      },
      {
        label: "关闭文件夹",
      },
    ],
  },
  {
    label: "bianji",
  },
];
1.13.2 setApplicationMenu 

将 menu 设置为 macOS 上的应用菜单。在 Windows 和 Linux 上,menu 将被设置为每个窗口的顶部菜单。

Menu.setApplicationMenu(menu)

1.14 MessageChannelMain

主进程中用于通道消息传递的通道接口。内置实例属性。

1.15 MessagePortMain

主进程中通道消息传递的端口接口。内置实例事件、实例方法。

1.16 nativeImage

使用 PNG 或 JPG 文件创建托盘、停靠栏和应用图标。内置方法、实例属性、实例方法。

1.17 nativeTheme

阅读并响应 Chromium 原生颜色主题的变化。内置事件、属性。

1.18 net

使用 Chromium 的原生网络库发出 HTTP/HTTPS 请求。内置方法、属性。

1.19 netLog

记录会话的网络事件。内置方法、属性。

1.20 Notification

创建操作系统桌面通知。内置实例事件、静态方法、实例属性、实例方法。

1.21 parentPort

与父进程通信的接口。内置事件、方法。

1.22 powerMonitor

监视电源状态变化。内置事件、方法、属性。

1.23 powerSaveBlocker

阻止系统进入低功耗(睡眠)模式。内置方法。

1.24 process

流程对象的扩展。内置事件、方法、属性。

1.25 protocol

注册自定义协议并拦截现有协议请求。内置方法。

1.26 pushNotifications

注册远程推送通知服务并接收来自远程推送通知服务的通知。内置事件、方法。

1.27 safeStorage

允许访问存储在本地计算机上的字符串的简单加密和解密。内置方法。

1.28 screen

检索有关屏幕尺寸、显示、光标位置等的信息。内置事件、方法。

1.29 session

管理浏览器会话、cookie、缓存、代理设置等。内置方法、属性、实例事件、实例属性、实例方法。

1.30 ShareMenu

在 macOS 上创建共享菜单。内置实例方法。

1.31 shell

使用默认应用管理文件和 URL。内置方法。

1.32 systemPreferences

获取系统偏好设置。内置事件、方法、属性。

1.33 TouchBar

为原生 macOS 应用创建 TouchBar 布局。内置静态属性、实例属性。

1.34 Tray

将图标和上下文菜单添加到系统的通知区域。内置实例事件、实例方法。

1.35 utilityProcess

utilityProcess 创建一个启用 Node.js 和消息端口的子进程。内置方法、实例事件、实例属性、实例方法。

1.36 webContents

渲染和控制网页。内置方法、实例事件、实例属性、实例方法。

1.37 WebContentsView

显示 WebContents 的视图。内置实例属性。

1.38 webFrameMain

控制网页和 iframe。内置实例事件、实例属性、实例方法。

1.39 View

创建和布局原生视图。内置实例事件、实例属性、实例方法。

2. 渲染器处理模块

2.1 clipboard

在系统剪贴板上执行复制和粘贴操作。内置方法。

2.2 contextBridge

在隔离的上下文之间创建安全、双向、同步的桥梁。内置方法。

2.3 crashReporter

同主进程属性一致

2.4 ipcRenderer

从渲染器进程到主进程异步通信。内置方法。

2.5 nativeImage

同主进程属性一致

2.6 webFrame

自定义当前网页的渲染。内置方法、属性。

2.7 webUtils

与 Web API 对象(文件、Blob 等)交互的实用程序层。内置方法。

3. 类

3.1 ClientRequest

发出 HTTP/HTTPS 请求。

3.2 CommandLine

操作 Chromium 读取的应用的命令行参数

3.3 Cookies

查询和修改会话的 cookie。

3.4 调试器

Chrome 远程调试协议的替代传输。

3.5 Dock

在 macOS Dock 中控制你的应用

3.6 DownloadItem

控制从远程源下载文件。

3.7 IncomingMessage

处理对 HTTP/HTTPS 请求的响应。

3.8 MenuItem

将项目添加到原生应用菜单和上下文菜单。

3.9 NavigationHistory

管理导航条目列表,代表用户在应用内的浏览历史记录。

3.10 ServiceWorkers

查询并接收来自会话活动服务工作者的事件。

3.11 触摸栏按钮

在触摸栏中为原生 macOS 应用创建一个按钮

3.12 TouchBar 颜色选择器

在触摸栏中为原生 macOS 应用创建颜色选择器

3.13 TouchBar 组

在触摸栏中为原生 macOS 应用创建一个组

3.14 TouchBar 标签

在触摸栏中为原生 macOS 应用创建标签

3.15 TouchBarOtherItemsProxy

实例化一个特殊的 "其他条目代理",它将继承自 Chromium 的 TouchBar 元素嵌套在代理指示的空间处。

3.16 触摸栏弹出框

在触摸栏中为原生 macOS 应用创建弹出窗口

3.17 触控栏清理器

创建一个洗涤器(可滚动选择器)

3.18 TouchBar 分段控件

创建分段控件(按钮组),其中一个按钮具有选定状态

3.19 TouchBar 滑块

在触摸栏中为原生 macOS 应用创建滑块

3.20 TouchBar 垫片

在原生 macOS 应用的触摸栏中的两个项目之间创建间隔

3.21 WebRequest

在请求生命周期的各个阶段拦截并修改请求的内容。

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

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

相关文章

【Python-办公自动化】1秒提取多个word表格汇总至1个excel内

欢迎来到"花花 Show Python",一名热爱编程和分享知识的技术博主。在这里,我将与您一同探索Python的奥秘,分享编程技巧、项目实践和学习心得。无论您是编程新手还是资深开发者,都能在这里找到有价值的信息和灵感。 自我介绍: 我热衷于将复杂的技术概念以简单易懂…

苹果上架没有iphone、没有ipad也可以生成截屏

使用flutter、uniapp或其他跨平台框架开发ios的APP&#xff0c;上架的时候都会遇到一个问题&#xff0c;上架的时候需要各种尺寸的设备来做ios截屏。 比如目前最新的要求是&#xff0c;iphone需要三种不同尺寸的设备的截屏&#xff0c;假如支持ipad则还需要使用ipad 2代和ipad…

linux常用命令学习-ls命令

1.1 ls 命令 命令功能&#xff1a;查看文件信息。 在 ubuntu 上&#xff0c;一般都使用 ls 命令来查看文件信息&#xff0c;ls ,是 list 这个单词的缩写。在当前目录下输入 ls 命令&#xff0c;这样就会列出当前路径下的全部文件&#xff0c;例如我们要查看桌面上的文件&#x…

什么是硬件在环仿真?

硬件在环Hardware-in-the-loop&#xff08;HIL&#xff09;仿真是一种实时仿真。您可以使用HIL模拟来测试您的控制器设计。HIL模拟显示了控制器如何实时响应逼真的虚拟刺激。您还可以使用HIL来确定您的物理系统&#xff08;设备&#xff09;模型是否有效。 在HIL模拟中&#xf…

代码随想录训练营 Day34打卡 动态规划 part02 62. 不同路径 63. 不同路径 II 343. 整数拆分 96. 不同的二叉搜索树

代码随想录训练营 Day34打卡 动态规划 part02 一、力扣62. 不同路径 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Fini…

5.vue中axios封装工程化

vue工程化中axios封装 视频演示地址&#xff1a;https://www.bilibili.com/video/BV121egeQEHg/?vd_source0f4eae2845bd3b24b877e4586ffda69a 通常我们封装需要封装request.js基础的发送请求工具类&#xff0c;再根据业务封装service类&#xff0c;service类是具体业务的接口…

Ps:首选项 - 暂存盘

Ps菜单&#xff1a;编辑/首选项 Edit/Preferences 快捷键&#xff1a;Ctrl K Photoshop 首选项中的“暂存盘” Scratch Disks选项卡通过合理配置和管理暂存盘&#xff0c;可以显著提高 Photoshop 的运行性能&#xff0c;特别是在处理复杂的设计项目或大型图像文件时。选择合适…

Conformer解析

文章目录 前言Conformer encoder model architectureConvolution SubsamplingLinear & DropoutConformer BlocksFeed Forward ModuleMulti-Headed Self-Attention ModuleConvolution Module 前言 Conformer encoder model architecture 对于语音来说&#xff0c;整个架构…

内核链表的实现

内核链表和普通链表的区别&#xff1a; 1. 普通链表当中数据域和指针域&#xff0c;没有做到区分&#xff0c;数据与指针形成了一个整体&#xff0c;而内核链表数据与指针是完全剥离的没有直接的关系。 2. 在普通链表当中所有节点的数据都是一样的类型&#xff0c;而内核链表…

vmware安装openEuler操作系统

文章目录 vmware安装openEuler操作系统官网地址下载方式 新建虚拟机新建虚拟机新建虚拟机向导输入新建的虚拟机名称预览安装虚拟机的操作系统开始安装语言选项基础配置 网络配置关机拍快照克隆模板机 vmware安装openEuler操作系统 官网地址 https://www.openeuler.org/zh/dow…

6.4 MySQL 常见查询优化案例分析

欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;欢迎订阅相关专栏&#xff1a; 工&#x1f497;重&#x1f497;hao&#x1f497;&#xff1a;野老杂谈 ⭐️ 全网最全IT互联网公司面试宝典&#xff1a;收集整理全网各大IT互联网公司技术、项目、HR面试真题.…

Python 函数参数介绍

目录 函数 -- 普通参数 函数 -- 参数进一步 -- 指定参数 函数 -- 参数带 * -- 将传入的参数打包成元组 函数 -- 参数带 ** -- 关键字传参 -- 将传入的参数打包成字典 综合使用 函数 -- 普通参数 函数 -- 参数进一步 -- 指定参数 函数调用时&#xff0c;未指定的参数需要写…

风清扬/基于Java语言的光伏监控系统+光伏发电预测+光伏项目+光伏运维+光伏储能项目

基于Java语言的光伏监控系统光伏发电预测光伏项目光伏运维光伏储能项目 介绍 基于Java语言的光伏监控系统光伏发电系统光伏软件系统光伏监控系统源码光伏发电系统源码 基于Java语言的光伏监控系统光伏发电预测光伏项目光伏运维光伏储能项目 安装教程 参与贡献 Fork 本仓库新…

十分钟搭建一个RTMP服务器

使用SRS搭建RTMP服务器 如果您需要搭建一个RTMP服务器&#xff0c;您可以使用SRS&#xff08;Simple-RTMP-Server&#xff09;来完成此任务。SRS是一个开源的RTMP服务器下面是一个简单的步骤指南&#xff1a; 获取srs srs官⽹&#xff1a;https://github.com/ossrs/srs 码云…

软考2024下半年软考报名时间安排及报名流程

简介 软件资格考试也称计算机软件水平考试 [1]&#xff0c;是原中国计算机软件专业技术资格和水平考试的完善与发展。是对从事或准备从事计算机应用技术、网络、信息系统和信息服务等专业技术工作的人员水平和能力的测试。这项考试是由国家人力资源和社会保障部、工业和信息化…

【通信协议】I2C总线(一主多从)

目录 I2C简介 硬件电路 软件模拟初始化 基本单元 起始信号 停止信号 发送一个字节 接收一个字节 发送应答 接收应答 I2C基本单元代码 MyI2C.h MyI2C.c 完整数据帧 学习资料分享 本博客使用软件模拟的代码进行I2C总线​​​​​​&#xff08;总线指多个设备共用…

【Python机器学习系列】使用Hyperopt搜索随机森林分类模型最优超参数(案例+源码)

这是我的第342篇原创文章。 一、引言 Hyperopt是一个强大的python库&#xff0c;用于超参数优化&#xff0c;由jamesbergstra开发。Hyperopt使用贝叶斯优化的形式进行参数调整&#xff0c;允许你为给定模型获得最佳参数。它可以在大范围内优化具有数百个参数的模型。 在本节中…

Vue3.0生命周期钩子(包含:Vue 2.0 和 Vue 3.0)

1、Vue 2.0 生命周期钩子 每个应用程序实例在创建时都有一系列的初始化步骤。例如&#xff0c;创建数据绑定、编译模板、将实例挂载到 DOM 并在数据变化时触发 DOM 更新、销毁实例等。在这个过程中会运行一些叫做生命周期钩子的函数&#xff0c;通过这些钩子函数可以定义业务逻…

【STM32+HAL】巡逻打靶小车

一、前言 作为电赛最爱出的小车和视觉题&#xff0c;将两者结合起来出题也是一个方向&#xff0c;故写下此文供学者参考&#xff0c;也作为备赛电赛的记录。 如有小伙伴想交流学习心得&#xff0c;欢迎加入群聊751950234&#xff0c;群内不定期更新代码&#xff0c;以及提供本…

elasticsearch的高亮查询三种模式查询及可能存在的问题

目录 高亮查询使用介绍 高亮参数 三种分析器 可能存在的查询问题 fvh查询时出现StringIndexOutOfBoundsException越界 检索高亮不正确 参考文档 高亮查询使用介绍 Elasticsearch 的高亮&#xff08;highlight&#xff09;可以从搜索结果中的一个或多个字段中获取突出显…