<Rust><GUI>rust语言GUI库tauri体验:前、后端结合创建一个窗口并修改其样式
前言
 本文是rust语言下的GUI库:tauri来创建一个窗口的简单演示,主要说明一下,使用tauri这个库如何创建GUI以及如何添加部件、如何编写逻辑、如何修改风格等,所以,这也是一个专栏,将包括tauri库的多个方面。
 
环境配置
 系统:windows
 平台:visual studio code
 语言:rust、javascript、html、css
 库:tauri
概述
 本文是tauri库系列博文的第一篇,主要是简单实现一个窗口程序并成功运行,当然,这是基于官方的示例,事实上官方给出的上手例程非常详细,不过,本文在官方示例的基础上,将会做一些修改和延伸。
窗口示例
首先我们来看官方示例,tauri官方给出了一个新手教程,教导你如何快速创建并显示一个窗口,当然,这是最简单的窗口,不过,这个样例基本上涉及了tauri的整个原理。
 首先,tauri是前后端结合的一种实现,它的页面创建、显示是使用的前端语言,你可以使用当前的任意前端语言来编写页面布局,比如:
 
 我对前端编程不是很熟悉,因此选择了第一个即原生的javascript结合html和css来编写页面。
 首先,在你的项目文件夹下,创建一个新文件夹,可以命名为ui,然后在ui文件夹下新建一个html文件,里面添加一些基本的内容:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>文档</title></head><body><h1>这是来自 Tauri 的欢迎!</h1></body>
</html>
 
以上内容,相信懂前端的朋友会很熟悉,如果你用浏览器运行这段代码,其显示如下:
 
 所以,你应该了解了,tauri所谓的GUI其实就是和网页显示是一样的,只是封装成了窗口程序。这就是前端和后端的结合,前端使用的是html和js,后端呢,使用的则是rust。
 好了,我们按照例程,新建了html文件,暂且先放着,然后我们要在项目路径下,创建rust文件。
 对于初学者来说,官方建议使用tauri cli来管理rust代码,所以你需要先安装tauri cli:
cargo install tauri-cli
 
等待安装完成,然后来创建一个tauri下的rust项目:
cargo tauri init
 
当你运行这个指令时,tauri会让你“回答”几个问题,我们按照例程所示一一填写即可。
 1、应用名称:输入你自定义的名字即可
 2、窗口标题:就是生成的窗口的title,你可以输入一个自定义名称,后面也可以再修改
 3、前端页面文件所在位置:输入你之前创建的ui文件夹路径,可以和官方一样使用"…/ui"这个路径,也可以根据你自己创建的文件夹路径来填写
 4、开发环境时路径:和3一致
 5、使用什么命令来开发前端:暂时不填
 6、使用什么命令来构建前端:暂时不填
以上6个问题,填前4个就行,5、6暂时不填,因为涉及后期使用其他命令来开发前端的程序,但暂时你可能还不会或者不需要这样复杂的命令。
 
回答完问题后,tauri会自动创建一个包含rust代码的文件夹,通常文件夹名称默认为src-tauri,其目录层级如下:
 
 我们先打开src文件夹下的main.rs文件,其内部代码如下:
 #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]fn main() {
tauri::Builder::default().run(tauri::generate_context!()).expect("error while running tauri application");
}
 
main函数是rust程序的进入点,tauri在此创建窗口的初始化程序。
 如果你这直接运行,使用cargo tauri dev
 会得到一个和之前的网页所示一样画面的窗口画面。(首次编译时间可能会比较长)
 
 以上是最简单的示例程序,基本上窗口是用html布局实现的,还没有涉及rust代码,下面看一下如何在html中调用rust函数来实现某些功能,比如实现文本内容的更改。
 我们首先在main.rs中创建一个函数:
#[tauri::command]
fn greet(name: &str) -> String {format!("Hello, {}!", name)
}
 
这里,greet是rust中的普通函数,但是为其添加了#[tauri::command]宏,这样一来,greet函数就可以与js进行交互了。但是,还需要让tauri知道这个函数,所以需要注册它:
fn main() {tauri::Builder::default().invoke_handler(tauri::generate_handler![greet]).run(tauri::generate_context!()).expect("error while running tauri application");
}
 
如上,在原先的main函数里增加了一条.invoke_handler()函数,配合Generate_handler![]宏来注册greet函数。这样,就可以在前端代码里调用rust的函数功能了。
 将之前的index.html代码修改一下:
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><h1 id="header">Welcome from Tauri!</h1><script>// access the pre-bundled global API functionsconst { invoke } = window.__TAURI__.tauri// now we can call our Command!// You will see "Welcome from Tauri" replaced// by "Hello, World!"!invoke('greet', { name: 'World' })// `invoke` returns a Promise.then((response) => {window.header.innerHTML = response})</script></body>
</html>
 
到此,都是官方提供的代码,对于前端的API调用,我不是很熟悉,但是我也不用管它,直接照做就行,目的是引用rust的函数,在上面的代码里,invoke后面的参数,第一个greet表示函数名,第二个是函数的参数名:
#[tauri::command]
fn greet(name: &str) -> String {format!("Hello, {}!", name)
}
 
invoke返回的是一个Pormise,据我粗浅的了解,Promise是一个异步操作,但这里并没有使用异步关键词,而是使用then来取得反馈response,关于前端,目前了解尚不多,所以此处我只关心其结果,根据官方示例,response就是函数greet运行后的输出,在此处的示例代码中,输出应该是:
Hello,World
然后将Hello,World传给当前页面的id为header的标签,即修改标签的内容为:
 Hello,World
但是,需要注意的是,如果要rust中的注册函数起作用,需要修改一下tauri.conf.json文件的内容:
"build": {"beforeBuildCommand": "","beforeDevCommand": "","devPath": "../tau-ui","distDir": "../tau-ui","withGlobalTauri":true}
 
如上,在这个json文件里,为build选项添加withGlobalTauri参数,并将其设为true。
 这是一个临时办法,在以后会使用 @tauri-apps/api包,但在目前的初学者教程里,不涉及这么复杂的内容。
再次运行程序:
 
 以上,实现的是官方的示例程序,下面我们来作一下扩展,我们为页面添加一个按钮以及一条标签,然后点击按钮后,标签显示相应的内容,标签的内容由rust的函数提供。
 所以,我们在main.rs中再添加一个函数:
#[tauri::command]
fn sendstring()->String{"来自rust的字符串".to_string()
}
 
然后注册到tauri:
fn main() {tauri::Builder::default().invoke_handler(tauri::generate_handler![greet,sendstring]).run(tauri::generate_context!()).expect("error while running tauri application");
}
 
然后,我们在index.html文件中添加一个按钮和标签:
  <button id="btn1" onclick="">按钮1</button><p id="p1">hello,rust</p>
 
然后为按钮的点击事件绑定一个脚本函数:
 <button id="btn1" onclick="recvstring()">按钮1</button>
 
 function recvstring(){var elem=document.getElementById("p1");invoke('sendstring',{}).then((response)=>{elem.innerHTML=response;})}
 
然后再次运行程序:
 
 点击按钮:
 
 成功的执行了rust中注册的函数。
综上,tauri的使用体验,如果熟悉前端开发,我觉得还是不错的,因为虽然其后端使用的是rust,但是这仅在你的js无法满足开发的时候,我们就可以利用rust的强大功能来编写需要的函数,但是如果你要制作比较简单的程序,那么仅是js就完全满足开发了,就和开发网页程序是一样的,只是tauri封装成了桌面程序。
相比于iced以及egui这类rust的GUI库,我觉得 tauri的优点就是页面布局,感觉要方便很多,但目前我还没有去测试tauri的通讯,比如websocket等,不过,从体验上来说,tauri在github上排名rust gui库第一,的确是有道理的。
相关文章:
<Rust><GUI>rust语言GUI库tauri体验:前、后端结合创建一个窗口并修改其样式
前言 本文是rust语言下的GUI库:tauri来创建一个窗口的简单演示,主要说明一下,使用tauri这个库如何创建GUI以及如何添加部件、如何编写逻辑、如何修改风格等,所以,这也是一个专栏,将包括tauri库的多个方面。…...
OBD诊断(ISO15031) 09服务
文章目录 功能简介ISO 9141-2、ISO 14230-4和SAE J1850的诊断服务定义1、请求车辆信息请求消息(读取支持的INFOTYPE)2、请求车辆信息响应消息(报告支持INFOTYPE)3、请求车辆信息请求消息(读取INFOTYPE值)4、请求车辆信息响应消息&…...
客户端与服务端之间的通信连接
目录 那什么是Socket? 什么是ServerSocket? 代码展示: 代码解析: 补充: 输入流(InputStream): 输出流(OutputStream): BufferedReader 是如何提高读取效率的&a…...
Font Awesome 图表图标
Font Awesome 图表图标 Font Awesome 是一个广泛使用的图标库,它提供了大量的图标,可以轻松地用于网页设计和开发中。在本文中,我们将重点介绍 Font Awesome 中的图表图标,探讨它们的特点、使用方法,并展示一些实际的…...
React Native 自定义 Hook 获取组件位置和大小
在 React Native 中自定义 Hook useLayout 获取 View、Pressable 等组件的位置和大小的信息 import {useState, useCallback} from react import {LayoutChangeEvent, LayoutRectangle} from react-nativeexport function useLayout() {const [layout, setLayout] useState&l…...
如何在SpringCloud中使用Kafka Streams实现实时数据处理
使用Kafka Streams在Spring Cloud中实现实时数据处理可以帮助我们构建可扩展、高性能的实时数据处理应用。Kafka Streams是一个基于Kafka的流处理库,它可以用来处理流式数据,进行流式计算和转换操作。 下面将介绍如何在Spring Cloud中使用Kafka Streams实…...
InterSystems IRIS使用python pyodbc连接 windows环境,odbc驱动安装,DSN配置,数据源配置
一、创建的数据库和数据 SELECT 1SELECT $ZVERSIONCREATE TABLE MyApp.Person ( ID INT PRIMARY KEY, Name VARCHAR(100) NOT NULL, Age INT, Gender CHAR(1) );CREATE TABLE MyApp.Person2 ( ID INT PRIMARY KEY, Name VARCHAR(100) NOT NULL, Age INT, Gender CHA…...
JVM:运行时数据区
文章目录 一、总览二、程序计数器1、介绍2、程序计数器在运行中会出现内存溢出吗? 三、栈1、介绍2、栈帧的组成部分(1)局部变量表(2)操作数栈(3)帧数据(3)栈内存溢出&…...
spring-boot2.x整合Kafka步骤
1.pom依赖添加 <properties><java.version>1.8</java.version><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</ma…...
信创学习笔记(四),信创之数据库DB思维导图
创作不易 只因热爱!! 热衷分享,一起成长! “你的鼓励就是我努力付出的动力” 一. 信创学习回顾 1.信创内容 信创内容思维导图 2.信创之CPU芯片架构 信创之CPU芯片架构思维导图 3.信创之操作系统OS 信创之操作系统OS思维导图 二. 信创之国产数据库DB思维导图 …...
SCP 使用教程
SCP(Secure Copy Protocol)是一种通过加密的方式在本地主机和远程主机之间安全地传输文件的协议。它是基于SSH协议的扩展,允许用户在不同主机之间进行文件复制和传输,是Linux和Unix系统中常用的工具之一。本教程将详细介绍SCP的基…...
python自动化之用flask校验接口token(把token作为参数)
用到的库:flask 实现效果: 写一个接口,需要token正确才能登录 代码: # 导包 from flask import Flask,request,jsonify,json # 创建一个服务 appFlask(__name__) # post请求,路径:/query app.route(/query, met…...
旗晟巡检机器人的应用场景有哪些?
巡检机器人作为现代科技的杰出成果,已广泛应用于各个关键场景。从危险的工业现场到至关重要的基础设施,它们的身影无处不在。它们以精准、高效、不知疲倦的特性,担当起保障生产、守护安全的重任,为行业发展注入新的活力。那么&…...
vue2迁移到vue3注意点
vue2迁移到vue3注意点 1、插槽的修改 使用 #default , 以及加上template 模板 2、 类型的定义,以及路由,vue相关资源(ref, reactive,watch)的引入等 3、类装饰器 1)vue-class-component是vue官方库,作…...
使用windows批量解压和布局ImageNet ISLVRC2012数据集
使用的系统是windows,找到的解压命令很多都linux系统中的,为了能在windows系统下使用,因此下载Git这个软件,在其中的Git Bash中使用以下命令,因为Git Bash集成了很多linux的命令,方便我们的使用。 ImageNe…...
css实现每个小盒子占32%,超出就换行
代码 <div class"visitors"><visitor class"item" v-for"(user,index) in userArr" :key"user.id" :user"user" :index"index"></visitor></div><style lang"scss" scoped&…...
C++的链接指示extern “C“
目录 链接指示extern "C"A.What(概念)B.Why(extern "C"的作用)C.How (如何使用链接指示extern "C") 链接指示extern “C” A.What(概念) extern&quo…...
私域运营 组织架构
**揭秘私域社群运营的神秘面纱:角色与职能一网打尽!** 在私域社群运营的大舞台上,每个角色都扮演着不可或缺的重要角色。今天,就让我们一起揭开这个神秘世界的面纱,看看这些角色们是如何协同作战,共同创造…...
Netty HTTP
Netty 是一个高性能的异步事件驱动的网络应用程序框架,支持快速开发可维护的高性能协议服务器和客户端。它广泛应用于开发网络应用程序,如服务器和客户端协议的实现。Netty 提供了对多种传输类型的抽象,如 TCP/IP 和 UDP/IP 等,使…...
什么是边缘计算技术和边缘计算平台?
随着物联网、5G技术和人工智能的不断发展,数据的规模和种类也在快速增加。在这种背景下,传统的云计算模式面临着一些问题,例如延迟高、网络拥塞等,这些问题限制了数据的处理速度和效率,降低了用户的使用体验。为了解决…...
UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
观成科技:隐蔽隧道工具Ligolo-ng加密流量分析
1.工具介绍 Ligolo-ng是一款由go编写的高效隧道工具,该工具基于TUN接口实现其功能,利用反向TCP/TLS连接建立一条隐蔽的通信信道,支持使用Let’s Encrypt自动生成证书。Ligolo-ng的通信隐蔽性体现在其支持多种连接方式,适应复杂网…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...
《基于Apache Flink的流处理》笔记
思维导图 1-3 章 4-7章 8-11 章 参考资料 源码: https://github.com/streaming-with-flink 博客 https://flink.apache.org/bloghttps://www.ververica.com/blog 聚会及会议 https://flink-forward.orghttps://www.meetup.com/topics/apache-flink https://n…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
前端开发面试题总结-JavaScript篇(一)
文章目录 JavaScript高频问答一、作用域与闭包1.什么是闭包(Closure)?闭包有什么应用场景和潜在问题?2.解释 JavaScript 的作用域链(Scope Chain) 二、原型与继承3.原型链是什么?如何实现继承&a…...
自然语言处理——循环神经网络
自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元(GRU)长短期记忆神经网络(LSTM)…...
JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案
JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停 1. 安全点(Safepoint)阻塞 现象:JVM暂停但无GC日志,日志显示No GCs detected。原因:JVM等待所有线程进入安全点(如…...
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
