首页 > 其他分享 >Tauri教程-进阶篇-第一节 自定义启动画面

Tauri教程-进阶篇-第一节 自定义启动画面

时间:2025-01-15 12:00:42浏览次数:3  
标签:tauri task 自定义 setup state Tauri 进阶篇 window app

请添加图片描述

“如果结果不如你所愿,就在尘埃落定前奋力一搏。”——《夏目友人帐》
“有些事不是看到了希望才去坚持,而是因为坚持才会看到希望。”——《十宗罪》
“维持现状意味着空耗你的努力和生命。”——纪伯伦

Tauri 技术教程 * 第五章 Tauri的进阶教程
第一节 自定义启动画面

一. 概述

在CS端大多数项目启动都会有一个代表性的启动界面,者本章节中我们将了解如何在Tauri项目中自定义自动界面。

本章节开始逐步涉及一些代码编程,本章节开始,章节射击的编码会统一放到我的GitCode上,可以结合使用,提升下学习效率。

二 . 创建启动画面

第一步 创建项目

这一步骤参见:第四章 第一节 项目创建及结构说明

第二步 在Tauri.conf.json 中注册窗口

在理我们的配置如下:

····
  "app": {
    "windows": [
      {
        "label": "main",
        "visible": false
      },
      {
        "label": "start",
        "url": "/start"
      }
    ],
    "security": {
      "csp": null
    }
  },
····

第三步 创建启动页面

启动页面的创建和我闷平时开发的页面没有区别,你可以借助vue或者react技术创建一个页面,这里我为了便捷创建一个html的页面,用于演示,实际开发中我也建议大家创建一个html页面,毕竟启动页面不是为了公告就是为了宣传。

start.html ,页面放置到项目根目录下

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>启动页面</title>
    <style>
      body,
      html {
        margin: 0;
        padding: 0;
        height: 100%;
        display: flex;
        justify-content: center;
        align-items: center;
        background-color: #f7f7f7;
      }
      .splash {
        text-align: center;
        font-family: "Arial", sans-serif;
        color: #333;
      }
      .splash h1 {
        font-size: 3em;
        margin-bottom: 0.5em;
      }
      .splash p {
        font-size: 1.2em;
      }
    </style>
  </head>
  <body>
    <div class="splash">
      <h1>欢迎来到我的网站</h1>
      <p>正在载入...</p>
    </div>
    <script>
      // 假设你有一个函数来检查加载状态
      function checkLoading() {
        // 假设当所有资源加载完毕后会设置一个特定的cookie或localStorage
        if (localStorage.getItem("loaded") === "true") {
          // 跳转到主页
          window.location.href = "index.html";
        } else {
          // 继续显示启动屏幕
          setTimeout(checkLoading, 100); // 每隔一段时间检查一次
        }
      }
      checkLoading();
    </script>
  </body>
</html>

效果如下:

在这里插入图片描述

第四步 配置页面

在理涉及到前后端的配置

  • 前端配置

    在src下创建start.ts,代码如下:

    import { invoke } from "@tauri-apps/api/core";
    
    function sleep(seconds: number): Promise<void> {
      return new Promise((resolve) => setTimeout(resolve, seconds * 1000));
    }
    
    async function setup() {
      console.log("前端应用启动..");
      await sleep(3);
      console.log("前端应用启动完成");
      // 调用后端应用
      invoke("set_complete", { task: "frontend" });
    }
    
    export default () => {
      // Effectively a JavaScript main function
      window.addEventListener("DOMContentLoaded", () => {
        setup();
      });
    };
    
    

    在main.ts 中引入

    import { createApp } from "vue";
    import App from "./App.vue";
    import start from "./start";
    
    createApp(App).mount("#app");
    
    start();
    
    
  • 后端配置

    • 安装依赖 tokio

      cd src-tauri
      cargo add tokio
      

      安装成功后会在cargo.toml 文件中,出现 tokio 的依赖配制

    • 在 src-tauri 的src 目录下 创建 tokio .rs 文件

      // Import functionalities we'll be using
      use std::sync::Mutex;
      use tauri::{AppHandle, Manager, State};
      use tokio::time::{sleep, Duration};
      
      
      
      // Create a struct we'll use to track the completion of
      // setup related tasks
      pub struct SetupState {
          pub(crate) frontend_task: bool,
          pub(crate) backend_task: bool,
      }
      
      // A custom task for setting the state of a setup task
      #[tauri::command]
      pub async fn set_complete(
          app: AppHandle,
          state: State<'_, Mutex<SetupState>>,
          task: String,
      ) -> Result<(), ()> {
          // Lock the state without write access
          let mut state_lock = state.lock().unwrap();
          match task.as_str() {
              "frontend" => state_lock.frontend_task = true,
              "backend" => state_lock.backend_task = true,
              _ => panic!("invalid task completed!"),
          }
          // Check if both tasks are completed
          if state_lock.backend_task && state_lock.frontend_task {
              // Setup is complete, we can close the splashscreen
              // and unhide the main window!
              let splash_window = app.get_webview_window("start").unwrap();
              let main_window = app.get_webview_window("main").unwrap();
              splash_window.close().unwrap();
              main_window.show().unwrap();
          }
          Ok(())
      }
      
      // An async function that does some heavy setup task
      pub async fn setup(app: AppHandle) -> Result<(), ()> {
          // Fake performing some heavy action for 3 seconds
          println!("Performing really heavy backend setup task...");
          sleep(Duration::from_secs(3)).await;
          println!("Backend setup task completed!");
          // Set the backend task as being completed
          // Commands can be ran as regular functions as long as you take
          // care of the input arguments yourself
          set_complete(
              app.clone(),
              app.state::<Mutex<SetupState>>(),
              "backend".to_string(),
          )
          .await?;
          Ok(())
      }
      
    • 在lib.rs 中引入

      mod tokio;
      use std::sync::Mutex;
      use tauri::async_runtime::spawn;
      use tokio::{set_complete,setup,SetupState};
      
      // Learn more about Tauri commands at https://tauri.app/develop/calling-rust/
      #[tauri::command]
      fn greet(name: &str) -> String {
          format!("Hello, {}! You've been greeted from Rust!", name)
      }
      
      // #[cfg_attr(mobile, tauri::mobile_entry_point)]
      // pub fn run() {
      //     tauri::Builder::default()
      //         .plugin(tauri_plugin_opener::init())
      //         .invoke_handler(tauri::generate_handler![greet])
      //         .run(tauri::generate_context!())
      //         .expect("error while running tauri application");
      // }
      
      // Our main entrypoint in a version 2 mobile compatible app
      #[cfg_attr(mobile, tauri::mobile_entry_point)]
      pub fn run() {
          // Don't write code before Tauri starts, write it in the
          // setup hook instead!
          tauri::Builder::default()
              // Register a `State` to be managed by Tauri
              // We need write access to it so we wrap it in a `Mutex`
              .manage(Mutex::new(SetupState {
                  frontend_task: false,
                  backend_task: false,
              }))
              // Add a command we can use to check
              .invoke_handler(tauri::generate_handler![greet, set_complete])
              // Use the setup hook to execute setup related tasks
              // Runs before the main loop, so no windows are yet created
              .setup(|app| {
                  // Spawn setup as a non-blocking task so the windows can be
                  // created and ran while it executes
                  spawn(setup(app.handle().clone()));
                  // The hook expects an Ok result
                  Ok(())
              })
              // Run the app
              .run(tauri::generate_context!())
              .expect("error while running tauri application");
      }
      
      

第五步 运行应用程序

现在您应该会看到一个启动画面窗口弹出,前端和后端都将执行各自 3 秒设置任务,之后启动画面消失并显示主窗口!
在这里插入图片描述

停留3秒后

在这里插入图片描述

遇到的问题及解决办法

  • 在启动项目时,控制台出现以下错误:

    note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
    

    解决办法:rust编译器提示你进行错误“回溯”:

    在window 下:Powershell

    $env:RUST_BACKTRACE=1 ; cargo run
    

    window cmd下:

    set RUST_BACKTRACE=1
    

    在linux与macos 下

    RUST_BACKTRACE=1 cargo run
    

标签:tauri,task,自定义,setup,state,Tauri,进阶篇,window,app
From: https://blog.csdn.net/sxlesq/article/details/145112068

相关文章

  • 如何自定义设置伪静态规则?
    关于您提到的如何自定义设置伪静态规则的问题,我们将为您提供详细的解决方案。伪静态(RewriteRules)是一种将动态URL转换为静态URL的技术,可以提高网站的SEO友好性并改善用户体验。不同类型的Web服务器有不同的配置方法,以下是针对几种常见服务器的详细说明。ApacheWeb服务器编辑......
  • Oracle自定义函数:生成汉字首字母拼音码的函数、MD5
    1 生成汉字拼音码的函数使用方法:select用户名.函数名(需要获取首字母拼音码的字段名)from用户名.表名;selectoracle_user1.fgetpy(t.name)fromoracle_user1.studentt;函数定义:createorreplacefunctionfgetpy(v_strvarchar2)returnvarchar2asv_strleni......
  • Origin 自定义公式拟合
    非线性拟合选中数据-绘图-分析-拟合-非线性曲线拟合-打开对话框-新建函数-函数命名-输入函数表达式,如y=a*x^2,即可。若公式中涉及到复数,则使用ImReal()取实部,Imaginary()取虚部,Imsqrt()取开方。如色散方程取实部,即色散部分进行拟合,则相应的Origin拟合......
  • 鸿蒙开发 - 自定义组件 和 组件通信的方法
    自定义组件的基本结构@Entry@ComponentstructMyComponent{build(){//...}}build()函数build()函数用于描述组件的UI界面,自定义组件必须定义build()函数build(){Column(){Text('测试')Button('点击')}}struct关键字strcut用来......
  • 界面控件 DevExpress v24.2 新版亮点 - 自定义和扩展 AI 驱动的扩展
    DevExpress拥有.NET开发需要的所有平台控件,包含600多个UI控件、报表平台、DevExpressDashboardeXpressApp框架、适用于VisualStudio的CodeRush等一系列辅助工具。屡获大奖的软件开发平台DevExpress今年第一个重要版本v23.1正式发布,该版本拥有众多新产品和数十个具有高影响力......
  • Winform自定义控件与案例 - 打造炫酷的自定义开关按钮控件
    文章目录1、控件效果2、开关控件需求说明3、案例实现1、属性扩展代码实现2、控件外观绘制3、事件实现4、拓展方法4、案例演示5、总结1、控件效果2、开关控件需求说明在开发Winform应用程序时,拥有一个美观且功能强大的UI控件库是非常重要的。本文将详细介绍如......
  • Tauri教程-基础篇-第六节 Tauri的调试与测试
    “如果结果不如你所愿,就在尘埃落定前奋力一搏。”——《夏目友人帐》“有些事不是看到了希望才去坚持,而是因为坚持才会看到希望。”——《十宗罪》“维持现状意味着空耗你的努力和生命。”——纪伯伦Tauri技术教程*第四章Tauri的基础教程第六节Tauri的调试与......
  • Django Admin 自定义操作封装
    1.为什么需要封装?在Django开发中,我们经常需要在Admin界面添加自定义操作按钮,以便管理员执行特定的任务。通过封装,我们可以:减少重复代码统一管理自定义操作的逻辑提高代码的可维护性和可扩展性©ivwdcwso(ID:u012172506)2.CustomActionMixin的实现让我们看看C......
  • 【Python】深入解析Python的上下文管理器与资源管理:实现自定义的`with`语句
    《PythonOpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门!解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界在现代编程中,资源管理的高效与安全性至关重要。Python通过上下文管理器与with语句为开发者提供了一种简洁而强大的资源管理机制。上下文管理器......
  • Qt 自定义控件(Qt绘图)
    一、QPaintEvent绘图事件1、QPaintEvent是Qt框架中一个重要的事件类,专门用于处理绘图事件。2、当Qt视图组件需要重绘自己的一部分时,就会产生QPaintEvent事件。3、Qt视图组件重绘自己,通常发生在以下情况: (1)、窗口第一次显示时:当窗口或控件第一次出现在屏幕上时,系统会生......