当前位置: 首页 > article >正文

【Tauri2】015——前端的事件、方法和invoke函数

目录

前言

正文

准备

关键url

获取所有命令

切换主题set_theme

设置大小

获得版本version

名字name

监听窗口移动


前言

【Tauri2】005——tauri::command属性与invoke函数-CSDN博客https://blog.csdn.net/qq_63401240/article/details/146581991?spm=1001.2014.3001.5502

【Tauri2】013——前端Window Event与创建Window-CSDN博客https://blog.csdn.net/qq_63401240/article/details/146981362?spm=1001.2014.3001.5502

笔者在013这篇文章中,发现window中事件,本质是在发送一个请求,还是post。笔者想尝试能否自己发送一个请求。

正文

准备

首先,笔者以window.hide()作为研究对象。需要隐藏的权限

主要代码

import {getCurrentWindow} from "@tauri-apps/api/window";export default function useWindowEvent() {let window = getCurrentWindow();window.onMoved((event) => {window.hide()})
}
  "permissions": [..."core:window:allow-hide"]

上面代码的意思是,移动事件中,触发隐藏窗口。

关键url

首先,可以在开发者工具发现这样的url

http://ipc.localhost/plugin%3Awindow%7Chide

设置断点

断的位置如下

首先,这个断下的文件的名字,笔者叫vm45,

vm是Virtual Machine的缩写,表示这段代码是在浏览器的虚拟机环境中运行的,这就很麻烦了

 可以发现Tauri-CallbackTauri-Error,Tauri-Invoke-Key

这三个参数是非常关键的

笔者发现Tauri-CallbackTauri-Error,都是数字,后面再说

Tauri-Invoke-Key的定义如下

const __TAURI_INVOKE_KEY__ = JSON.parse('"Oeln}Dgql8BzP843PEb!"')

但是每次运行,都不一样。笔者也不知道如何生成的。

不改变,继续使用,会报错,比如

__TAURI_INVOKE_KEY__ expected jW%TgoDn{gagRJ==SGXq but received !sN1d=nrX)Eqc&J(GS*f

 __TAURI_INVOKE_KEY__ 不对

但是,笔者在控制台报了这个错,然后再修改了__TAURI_INVOKE_KEY__ ,窗口就消失了,就成功了。哈哈哈哈

笔者在测试中发现了这个,没有用

INVOKE_KEY in tauri::test - RustThe invoke key used for tests.https://docs.rs/tauri/latest/tauri/test/constant.INVOKE_KEY.html

上面还有一段注释

  /**
   * A runtime generated key to ensure an IPC call comes from an initialized frame.
   *
   * This is declared outside the `window.__TAURI_INVOKE__` definition to prevent
   * the key from being leaked by `window.__TAURI_INVOKE__.toString()`.
   */

居然是运行时生成的。还防止泄露,可以

看来想自己发送请求,自己创造这个__TAURI_INVOKE_KEY__ ,不可行,反正笔者没有成功。

后面来实现这段代码。

看看messsage

{"cmd": "plugin:window|hide","callback": 1804441640,"error": 3457847102,"payload": {"label": "main"}
}

看到cmd,发现可以传递给invoke,因此,如下代码也可以实现隐藏

import {getCurrentWindow} from "@tauri-apps/api/window";
import {invoke} from "@tauri-apps/api/core";export default function useWindowEvent() {let window = getCurrentWindow();window.onMoved((event) => {invoke("plugin:window|hide", {"label": "main"})})
}

需要设置权限。

运行成功。哈哈哈哈

如果笔者把plugin:window|hide改成hide,url变成了

http://ipc.localhost/hide

 当然,结果报错。

看来url就是http://ipc.localhost/+cmd,原来如此。

而且观察cmd的格式plugin:window|hide

应该是  plugin:<plugin_name>|<plugin_function>

获取所有的cmd

笔者在tauri::command这个属性中,其中的wrapper中,进行了打印,如下。

  println!("函数名: {}", function.sig.ident);

打印结果如下,笔者把它全部输出了

函数名: version                                                                                                                                                                    
函数名: name
函数名: tauri_version
函数名: identifier
函数名: app_show
函数名: app_hide
函数名: fetch_data_store_identifiers
函数名: remove_data_store
函数名: default_window_icon
函数名: set_app_theme
函数名: listen                                                                                                                                                                     
函数名: unlisten
函数名: emit
函数名: emit_to
函数名: fetch
函数名: close                                                                                                                                                                      
函数名: get_all_webviews
函数名: create_webview_window
函数名: create_webview
函数名: webview_position
函数名: webview_size
函数名: print
函数名: webview_close
函数名: set_webview_size
函数名: set_webview_position                                                                                                                                                       
函数名: set_webview_focus
函数名: webview_hide
函数名: webview_show
函数名: set_webview_zoom
函数名: set_webview_background_color
函数名: clear_all_browsing_data
函数名: reparent
函数名: internal_toggle_devtools
函数名: get_all_windows
函数名: create
函数名: scale_factor
函数名: inner_position
函数名: outer_position
函数名: inner_size
函数名: outer_size
函数名: is_fullscreen
函数名: is_minimized
函数名: is_maximized
函数名: is_focused
函数名: is_decorated                                                                                                                                                               
函数名: is_resizable
函数名: is_maximizable
函数名: is_minimizable
函数名: is_closable
函数名: is_visible
函数名: is_enabled
函数名: title
函数名: current_monitor
函数名: primary_monitor
函数名: available_monitors
函数名: cursor_position
函数名: theme
函数名: is_always_on_top
函数名: center
函数名: request_user_attention
函数名: set_resizable
函数名: set_maximizable
函数名: set_minimizable
函数名: set_closable
函数名: set_title
函数名: maximize
函数名: unmaximize
函数名: minimize
函数名: unminimize
函数名: show
函数名: hide
函数名: close
函数名: destroy
函数名: set_decorations                                                                                                                                                            
函数名: set_shadow
函数名: set_effects
函数名: set_always_on_top
函数名: set_always_on_bottom
函数名: set_content_protected
函数名: set_size
函数名: set_min_size
函数名: set_max_size
函数名: set_position
函数名: set_fullscreen
函数名: set_focus
函数名: set_skip_taskbar
函数名: set_cursor_grab
函数名: set_cursor_visible
函数名: set_background_color
函数名: set_cursor_icon
函数名: set_cursor_position
函数名: set_ignore_cursor_events
函数名: start_dragging
函数名: start_resize_dragging
函数名: set_progress_bar
函数名: set_badge_count
函数名: set_visible_on_all_workspaces
函数名: set_title_bar_style
函数名: set_size_constraints
函数名: set_theme
函数名: set_enabled
函数名: set_overlay_icon
函数名: set_icon
函数名: toggle_maximize
函数名: internal_toggle_maximize
函数名: monitor_from_point
函数名: new                                                                                                                                                                        
函数名: from_bytes
函数名: from_path
函数名: rgba
函数名: size
函数名: new                                                                                                                                                                        
函数名: append
函数名: prepend
函数名: insert
函数名: remove
函数名: remove_at
函数名: items
函数名: get
函数名: popup
函数名: create_default
函数名: set_as_app_menu                                                                                                                                                            
函数名: set_as_window_menu
函数名: text
函数名: set_text
函数名: is_enabled
函数名: set_enabled
函数名: set_accelerator
函数名: set_as_windows_menu_for_nsapp
函数名: set_as_help_menu_for_nsapp
函数名: is_checked
函数名: set_checked
函数名: set_icon
函数名: resolve_directory                                                                                                                                                          
函数名: resolve
函数名: normalize
函数名: join
函数名: dirname
函数名: extname
函数名: basename
函数名: is_absolute

这些都是方法,笔者不敢确定是否都可以用

笔者尝试了一些方法

切换主题set_theme

需要权限  ——"core:window:allow-set-theme"

import './App.css'
import {getCurrentWindow} from "@tauri-apps/api/window";function App() {let window = getCurrentWindow();async function handleClick() {let get_theme = await window.theme();if(get_theme === "dark") {await window.setTheme("light");}else {await window.setTheme("dark");}}return (<><header><h1>My Tauri App</h1></header><main><div style={{ display: 'flex', gap: '10px' }}><button onClick={handleClick}>点击</button></div></main></>);
}export default App;

第二个url及负载

http://ipc.localhost/plugin%3Awindow%7Ctheme

label: "main"

第三个url及负载

http://ipc.localhost/plugin%3Awindow%7Cset_theme

label: "main"

value: "light"

 根据上面的信息,使用invoke实现的代码如下

    async function handleClick() {let get_theme = await invoke('plugin:window|theme',{'label':'main'});console.log(get_theme);if(get_theme === "dark") {await invoke('plugin:window|set_theme',{'label':'main','value':'light'});}else {await invoke('plugin:window|set_theme',{'label':'main','value':'dark'});}}

结果是成功的,哈哈哈哈哈哈

当然,感觉没什么用,相对来说,搞麻烦了。

但是,想不到这个invoke函数居然是这么关键,居然可以这样操作。

设置大小

再来试试,

权限core:window:allow-set-size

    async function handleClick() {let get_size=await window.innerSize();console.log(get_size);window.setSize(new PhysicalSize(1000, 500));}

观察请求

http://ipc.localhost/plugin%3Awindow%7Cinner_size

{label: "main"}

http://ipc.localhost/plugin%3Awindow%7Cset_size

{
  "label": "main",
  "value": {
    "Physical": {
      "width": 1000,
      "height": 500
    }
  }

因此,代码如下

    async function handleClick() {await invoke("plugin:window|set_size", {"label": "main","value": {"Physical": {"width": 1000,"height": 500}}});}

结果是可以的。哈哈哈哈

获得版本version

直接给出代码

    async function handleClick() {let version=await invoke("plugin:app|version")console.log("版本:",version)}

名字name

    async function handleClick() {let name=await invoke("plugin:app|name")console.log("名字:",name)}

 

监听窗口移动

简单地代码如下

import { getCurrentWindow } from "@tauri-apps/api/window";export async function useWindowEvent() {const window = getCurrentWindow();window.onMoved(()=>{console.log("窗口移动了");})}
onMoved(handler: EventCallback<PhysicalPosition>): Promise<UnlistenFn>;

 或者用listen,差不多。

使用invoke,应该怎么办?

先看看请求

http://ipc.localhost/plugin%3Aevent%7Clisten

{
  "event": "tauri://move",
  "target": {
    "kind": "Window",
    "label": "main"
  },
  "handler": 3468365674
}

这里面有个handler,很明显,是用来处理移动后的事件

如何自定义handler?

这就需要一个函数了——transformcallback

core | Taurihttps://v2.tauri.app/reference/javascript/api/namespacecore/#transformcallback

declare function transformCallback<T = unknown>(callback?: (response: T)=> void, once?: boolean): number;

第一个参数callback 是一个函数

第二个可选参数once 是boolean,判断是否使用一次。

返回一个数字

在前面,笔者提到,“Tauri-CallbackTauri-Error,都是数字”,很有可能就是这个函数的返回值。

综合上面的信息

最后,代码如下

import {transformCallback,invoke} from "@tauri-apps/api/core";
import {Event} from '@tauri-apps/api/event'export async function useWindowEvent() {const handlerId = transformCallback((event:Event<unknown>) => {console.log("窗口移动事件通过invoke实现:", event.payload);});await invoke("plugin:event|listen", {event: "tauri://move",target: { kind: "Window", label: "main" },handler: handlerId});
}

窗口隐藏

前面说了这么多,都是使用invoke,最后使用一下fetch

直接给出代码

import {transformCallback} from "@tauri-apps/api/core";
import {Event} from "@tauri-apps/api/event";export async function useWindowEvent() {const error=transformCallback((event:Event) => {console.log("失败")})const success=transformCallback((event:Event) => {console.log("成功")})const __TAURI_INVOKE_KEY__ = JSON.parse('"lZzIiQJ%t9b@}Q&aef^A"')fetch("http://ipc.localhost/plugin%3Awindow%7Chide", {method: 'POST',body: JSON.stringify({'label': 'main',}),headers: {'Content-Type': "application/json",'Tauri-Callback': success,'Tauri-Error': error,'Tauri-Invoke-Key': __TAURI_INVOKE_KEY__,}})}

笔者在代码中替换了,最后,成功了

怎么处理回调函数,笔者也不知道。

笔者还发现,只要不关闭程序,这个__TAURI_INVOKE_KEY__就可以使用

最后,虽然没有什么用。

哈哈哈哈

相关文章:

【Tauri2】015——前端的事件、方法和invoke函数

目录 前言 正文 准备 关键url 获取所有命令 切换主题set_theme 设置大小 获得版本version 名字name 监听窗口移动 前言 【Tauri2】005——tauri::command属性与invoke函数-CSDN博客https://blog.csdn.net/qq_63401240/article/details/146581991?spm1001.2014.3001.…...

密码学基础——分组密码的运行模式

前面的文章中文我们已经知道了分组密码是一种对称密钥密码体制&#xff0c;其工作原理可以概括为将明文消息分割成固定长度的分组&#xff0c;然后对每个分组分别进行加密处理。 下面介绍分组密码的运行模式 1.电码本模式&#xff08;ECB&#xff09; 2.密码分组链接模式&…...

Android SELinux权限使用

Android SELinux权限使用 一、SELinux开关 adb在线修改seLinux(也可以改配置文件彻底关闭) $ getenforce; //获取当前seLinux状态,Enforcing(表示已打开),Permissive(表示已关闭) $ setenforce 1; //打开seLinux $ setenforce 0; //关闭seLinux二、命令查看sel…...

Python----计算机视觉处理(Opencv:道路检测完整版:透视变换,提取车道线,车道线拟合,车道线显示,)

Python----计算机视觉处理&#xff08;Opencv:道路检测之道路透视变换) Python----计算机视觉处理&#xff08;Opencv:道路检测之提取车道线&#xff09; Python----计算机视觉处理&#xff08;Opencv:道路检测之车道线拟合&#xff09; Python----计算机视觉处理&#xff0…...

基于飞桨框架3.0本地DeepSeek-R1蒸馏版部署实战

深度学习框架与大模型技术的融合正推动人工智能应用的新一轮变革。百度飞桨&#xff08;PaddlePaddle&#xff09;作为国内首个自主研发、开源开放的深度学习平台&#xff0c;近期推出的3.0版本针对大模型时代的开发痛点进行了系统性革新。其核心创新包括“动静统一自动并行”&…...

docker初始环境搭建(docker、Docker Compose、portainer)

docker、Docker Compose和portainer的安装部署、使用 docker、Docker Compose和portainer的安装部署、使用一.安装docker1.失败的做法2.首先卸载旧版本&#xff08;没安装则下一步&#xff09;3.配置下载的yum来源&#xff0c;不然yum search搜不到4.安装启动docker5.替换国内源…...

开源RuoYi AI助手平台的未来趋势

近年来&#xff0c;人工智能技术的迅猛发展已经深刻地改变了我们的生活和工作方式。 无论是海外的GPT、Claude等国际知名AI助手&#xff0c;还是国内的DeepSeek、Kimi、Qwen等本土化解决方案&#xff0c;都为用户提供了前所未有的便利。然而&#xff0c;对于那些希望构建属于自…...

element-ui自制树形穿梭框

1、需求 由于业务特殊需求&#xff0c;想要element穿梭框功能&#xff0c;数据是二级树形结构&#xff0c;选中左边数据穿梭到右边后&#xff0c;左边数据不变。多次选中左边相同数据进行穿梭操作&#xff0c;右边数据会多次增加相同的数据。右边数据穿梭回左边时&#xff0c;…...

Linux系统学习Day04 阻塞特性,文件状态及文件夹查询

知识点4【文件的阻塞特性】 文件描述符 默认为 阻塞 的 比如&#xff1a;我们读取文件数据的时候&#xff0c;如果文件缓冲区没有数据&#xff0c;就需要等待数据的到来&#xff0c;这就是阻塞 当然写入的时候&#xff0c;如果发现缓冲区是满的&#xff0c;也需要等待刷新缓…...

Module模块化

导出&#xff1a;export关键字 export var color "red"; 重命名导出 在模块中使用as用导出名称表示本地名称。 import { add } from "./05-module-out.js"; 导入&#xff1a; import关键字 导入单个绑定 import { sum } from "./05-module-out.js&…...

Python基础——Pandas库

对象的创建 导入 Pandas 时&#xff0c;通常给其一个别名“pd”&#xff0c;即 import pandas as pd。作为标签库&#xff0c;Pandas 对象在 NumPy 数组基础上给予其行列标签。可以说&#xff0c;列表之于字典&#xff0c;就如 NumPy 之于 Pandas。Pandas 中&#xff0c;所有数…...

C++: 类型转换

C: 类型转换 &#xff08;一&#xff09;C语言中的类型转换volatile关键字 修饰const变量 &#xff08;二&#xff09;C四种强制类型转换1. static_cast2. reinterpret_cast3. const_cast4. dynamic_cast总结 (三)RTTI &#xff08;一&#xff09;C语言中的类型转换 在C语言中…...

[ctfshow web入门] 零基础版题解 目录(持续更新中)

ctfshow web入门 零基础版 前言 我在刷题之前没有学过php&#xff0c;但是会python和C&#xff0c;也就是说&#xff0c;如果你和我一样会一门高级语言&#xff0c;就可以开始刷题了。我会以完全没学过php的视角来写题解&#xff0c;你也完全没有必要专门学习php&#xff0c;这…...

【蓝桥杯】动态规划:线性动态规划

1. 最长上升子序列(LIS) 1.1. 题目 想象你有一排数字,比如:3, 1, 2, 1, 8, 5, 6 你要从中挑出一些数字,这些数字要满足两个条件: 你挑的数字的顺序要和原来序列中的顺序一致(不能打乱顺序) 你挑的数字要一个比一个大(严格递增) 问:最多能挑出多少个这样的数字? …...

STM32——DAC转换

DAC简介 DAC&#xff0c;全称&#xff1a;Digital-to-Analog Converter&#xff0c;扑指数字/模拟转换器 ADC和DAC是模拟电路与数字电路之间的桥梁 DAC的特性参数 1.分辨率&#xff1a; 表示模拟电压的最小增量&#xff0c;常用二进制位数表示&#xff0c;比如&#xff1a…...

Kafka的索引设计有什么亮点

想获取更多高质量的Java技术文章&#xff1f;欢迎访问Java技术小馆官网&#xff0c;持续更新优质内容&#xff0c;助力技术成长 Java技术小馆官网https://www.yuque.com/jtostring Kafka的索引设计有什么亮点&#xff1f; Kafka 之所以能在海量数据的传输和处理过程中保持高…...

在深度学习中,如何统计模型的 ​​FLOPs(浮点运算次数)​​ 和 ​​参数量(Params)

在深度学习中&#xff0c;统计模型的FLOPs&#xff08;浮点运算次数&#xff09;和参数量&#xff08;Params&#xff09;是评估模型复杂度和计算资源需求的重要步骤。 一、参数量&#xff08;Params&#xff09;计算 参数量指模型中所有可训练参数的总和&#xff0c;其计算与…...

智能手表该存什么音频和文本?场景化存储指南

文章目录 为什么需要“场景化存储”&#xff1f;智能手表的定位手机替代不了的场景碎片化的场景存储 音频篇&#xff1a;智能手表该存什么音乐和音频&#xff1f;运动场景通勤场景健康场景 文本篇&#xff1a;哪些文字信息值得放进手表&#xff1f;&#xff08;部分情况可使用图…...

Linux之Shell脚本--命令提示的写法

原文网址&#xff1a;Linux之Shell脚本--命令提示的写法-CSDN博客 简介 本文介绍Linux的Shell脚本命令提示的写法。 场景描述 在写脚本时经常会忘记怎么使用&#xff0c;需要进行命令提示。比如&#xff1a;输入-h参数&#xff0c;能打印用法。 实例 新建文件&#xff1a…...

Logo语言的进程

Logo语言的进程与发展 引言 Logo语言是一种专为儿童和教育目的而设计的编程语言&#xff0c;其独特之处在于其简洁的语法和直观的图形化界面&#xff0c;旨在帮助学生理解程序设计的基本概念。由于其在教育领域的广泛应用&#xff0c;Logo语言在编程教育史上占据了重要的地位…...

Day19 -实例:xcx逆向提取+微信开发者工具动态调试+bp动态抓包对小程序进行资产收集

思路&#xff1a; 拿到源码后的测试方向&#xff1a; Step1、xcx逆向提取源码 00x1 先将曾经使用小程序记录删除 00x2 访问小程序 例&#xff1a;汉川袁老四小程序 00x3 将文件给xcx进行逆向解包 xcx工具的目录下&#xff0c;wxpack文件夹内 Step2、微信开发者工具进行动态…...

鸿蒙Arkts开发飞机大战小游戏,包含无敌模式,自动射弹,暂停和继续

飞机大战可以把飞机改成图片&#xff0c;目前包含无敌模式&#xff0c;自动射弹&#xff0c;暂停和继续的功能 代码如下&#xff1a; // 定义位置类 class GamePosition {x: numbery: numberconstructor(x: number, y: number) {this.x xthis.y y} }Entry Component struct…...

ECharts配置优化

优化 ECharts 配置可以从性能优化、视觉优化和可维护性优化三个方面入手&#xff0c;下面我给你详细展开几个实用方向&#xff1a; ✅ 一、性能优化&#xff08;大数据量 or 页面卡顿时重点考虑&#xff09; 使用 setOption 的 notMerge 和 lazyUpdate chart.setOption(option,…...

从基础算力协作到超智融合,超算互联网助力大语言模型研习

一、背景 大语言模型&#xff08;LLMs&#xff09;的快速发展释放出了AI应用领域的巨大潜力。同时&#xff0c;大语言模型作为 AI领域的新兴且关键的技术进展&#xff0c;为 AI 带来了全新的发展方向和应用场景&#xff0c;给 AI 注入了新潜力&#xff0c;这体现在大语言模型独…...

M1使用docker制作镜像xxl-job,供自己使用

很苦逼一个情况,m1的docker假如不翻墙&#xff0c;我们找不到xxl-job,所以我们要自己制作 首先先去下载xxl-job源码https://gitee.com/xuxueli0323/xxl-job 你把它拉去到idea中 拉去成功后&#xff0c;进入这个xxl-job目录 执行 mvn clean package -Dmaven.test.skiptrue(这一步…...

Spring Boot 集成Redis 的Lua脚本详解

1. 对比Lua脚本方案与Redis自身事务 对比表格 对比维度Redis事务&#xff08;MULTI/EXEC&#xff09;Lua脚本方案原子性事务命令序列化执行&#xff0c;但中间可被其他命令打断&#xff0c;不保证原子性Lua脚本在Redis单线程中原子执行&#xff0c;不可中断计算能力仅支持Red…...

第一个简易SSM框架项目

引言 这是一个简易SSM整合项目&#xff0c;适合后端入门的练习项目&#xff0c;其中没有太多的业务操作&#xff0c;主要是这个框架&#xff0c;以及编码的顺序&#xff0c;希望大家有所收获 首先需要先配置环境 数据库环境 创建一个存放书籍的数据库表 create database s…...

Node.js局部生效的中间件

目录 1. 目录结构 2. 代码实现 2.1 安装Express 2.2 app.js - 主文件 2.3 authMiddleware.js - 局部生效的中间件 3. 程序运行结果 4. 总结 在Node.js的Express框架中&#xff0c;局部生效的中间件是指仅在特定路由或路由组中生效的中间件。它可以用于权限验证、数据过滤…...

Nginx 常见面试题

一、nginx常见错误及处理方法 1.1 404 bad request 一般原因&#xff1a;请求的Header过大 解决办法&#xff1a; 配置nginx.conf 相关设置1. client_header_buffer_size 16k; 2. large_client_header_buffers 4 64k;1.2 413 Request Entity Too Large 一般原因&#xff1…...

golang 计时器内存泄露问题 与 pprof 性能分析工具

&#xff08;上图用 go tool pprof 工具分析生成&#xff09; 这种会造成内存泄露 因为每次for都会新建一个time对象&#xff0c;只有到期后会被回收。 解决方法&#xff1a;用time.NewTimer与time.Reset每次重新激活定时器 背景 我先贴一下会发生内存泄漏的代码段&#xff0c…...