图形界面不难吗?

虽然我是初学者,但我觉得一旦成为GUI应用程序就很难创作作品。
最大的障碍是在审美意识之前引入异步处理。
“不是在做某个过程的时候就被冻结了吗?”
“可以存在哪些应用程序状态组合?”
“即使窗口大小、显示器分辨率等发生变化,它也能正常工作吗?”
“显示的项目与内部数据一致吗?”
除此之外,考虑操作系统差异等会让我头疼……不是吗?

那里有许多 GUI 工具包,但最热门的是电子和其他工具包。使用网络技术的桌面应用程序.
由于大多数操作系统都内置了类似 webview 的功能,因此感觉这项技术开始为跨平台应用程序铺平道路。
示例包括 Teams、Discord、Slack、VSCode 等。

Rust 中的 GUI 情况

Rust 本身是一种低级语言,旨在在没有操作系统的环境中工作,作为 C 的替代品。可能是因为这个原因,直到几年前,围绕 GUI 的库还不是很完善,到最后都不知道该用哪一个(有的可以和游戏引擎一起作为 GUI 使用,但是它们是稳定的)。什么都没有)。然而,在 2022 年 7 月 5 日,基于 webview 的 GUI 工具 Tauri 达到了 1.0 版本,成为经久耐用的产品。也就是说,几乎所有的webfront功能都被提升为UI工具了。路线图中也考虑了移动支持,我觉得这是一个非常有前途的工具。

触摸金牛座

老实说,我的文章向后兼容@namn1125的文章,所以如果你擅长前台,请阅读这篇文章。它更容易,更有趣 100 倍。

做什么

因为我的工作,我经常涉及机器视觉,所以我使用相机查看器。
使用 GUI 按钮从相机接收图像数据并显示获取的图像。
(图片)
【Tauri】Rustで画像を表示するだけのGUIアプリ作るよ

材料

  1. nodeJS
  2. nodeJS 的包管理器(似乎推荐使用纱线)
  3. 可以捕获图像的任何物理对象

    试着做

    您可以在yarn create tauri-app 开始一个项目。
    设置应用名称、标题和网页前端框架。我选择香草是因为我没有做任何花哨的东西。
    【Tauri】Rustで画像を表示するだけのGUIアプリ作るよ
    我喜欢 CUI 完成所有设置的事实。
    安装完成后
    【Tauri】Rustで画像を表示するだけのGUIアプリ作るよ
    键入这三行似乎更好,所以键入它们。
    您的应用程序将以开发模式运行。
    【Tauri】Rustで画像を表示するだけのGUIアプリ作るよ

    现在剩下的就是添加到此。
    显示的 HTML 为./dist/index.html,因此如图所示重写它。

    索引.html
    <meta charset="UTF-8">
    
    <body>
      <img src="" alt="" style="max-width: 100%;" id="image">
      <p>
        <input type="button" value="画像取得" id="getFrame">
      </p>
    </body>
    
    

    严重合适。如果未指定字符代码,则日语为乱码。

    接下来我们将编写后端。
    当按下正面的按钮时,这应该返回图像。
    前端和后端之间有两种类型的通信:事件和命令。
    在这种情况下,该命令是合适的,因为图像采集是从 HTML 按钮触发的。

    使 withGlobalTauri 为 true 以使用该命令。

    tauri.conf.json
    {
      "build": {
        "beforeBuildCommand": "",
        "beforeDevCommand": "",
        "devPath": "../ui",
        "distDir": "../ui",
        "withGlobalTauri": true
      },
    

    要注册命令,请将 #[tauri::command] 属性添加到 Rust 端的函数。
    我会按照教程跟你打招呼。

    矿。 rs
    #![cfg_attr(
        all(not(debug_assertions), target_os = "windows"),
        windows_subsystem = "windows"
    )]
    
    fn main() {
        tauri::Builder::default()
            .invoke_handler(tauri::generate_handler![greet])
            .run(tauri::generate_context!())
            .expect("error while running tauri application");
    }
    
    #[tauri::command]
    fn greet(name: &str) -> String {
        format!("Hello, {}!", name)
    }
    
    

    尝试从 devtool 控制台调用它。

    window.__TAURI__.invoke("greet", {name:"World"}).then((response ) => console.log(response))
    

    【Tauri】Rustで画像を表示するだけのGUIアプリ作るよ
    与 Rust 端的通信已完成。任何可以序列化的数据都可以交换。
    使用它以字节字符串的形式发送图像。

    矿。 rs
    #![cfg_attr(
        all(not(debug_assertions), target_os = "windows"),
        windows_subsystem = "windows"
    )]
    use opencv::{
        core::Vector,
        imgcodecs,
        prelude::*,
        videoio,
    };
    use std::sync::{Arc, Mutex};
    use tauri::State;
    
    struct Camera(Arc<Mutex<videoio::VideoCapture>>);
    
    #[tauri::command]
    async fn on_trigger(cam: State<'_, Camera>) -> Result<Vec<u8>, ()> {
        let mut cam = cam.0.lock().unwrap();
        let mut image = Mat::default();
        cam.read(&mut image).unwrap();
        let mut buf = Vector::default();
        imgcodecs::imencode(".png", &mut image, &mut buf, &Vector::default()).unwrap();
        Ok(buf.to_vec())
    }
    
    fn main() {
        let cam = videoio::VideoCapture::new(0, videoio::CAP_ANY).unwrap();
        tauri::Builder::default()
            .manage(Camera(Arc::new(Mutex::new(cam))))
            .invoke_handler(tauri::generate_handler![on_trigger])
            .run(tauri::generate_context!())
            .expect("error while running tauri application");
    }
    
    

    要将async fn转换为tauri::command,需要返回Result<T,E>(我有点上瘾了)
    如果您不这样做,您的所有应用程序将在编码期间被阻止。
    您可以使用 image crate 对图像进行编码。

    让我们也为按钮设置一个回调。

    索引.html
    <meta charset="UTF-8">
    
    <body>
      <img src="" alt="" style="max-width: 100%;" id="image">
      <p>
        <input type="button" value="画像取得" id="getFrame">
      </p>
    </body>
    
    <script>
      let image = document.getElementById("image");
      image.onload = () => window.URL.revokeObjectURL(image.src);
      let button = document.getElementById("getFrame");
      button.onclick = ()=>{
        window.__TAURI__.invoke("on_trigger").then((response ) => {
          image.src = window.URL.createObjectURL(new Blob([new Uint8Array(response)], { type: "image/png" }));
        })
      }
    </script>
    

    您现在应该能够看到图像。每次按下按钮时,图像都会更新。
    【Tauri】Rustで画像を表示するだけのGUIアプリ作るよ
    如果要做实时处理,是否需要WebRTC之类的技术?
    即使在发布版本中,我也觉得响应不如原生 GUI。

    题外话

    Opencv的VideoCapture只读取UVC相机,所以要使用工业相机,需要读取SDK并获取RGB8格式数组和图像大小。
    好在opencv-rs有Mat::from_slice,所以我可以管理。也许 ndarray 板条箱更充实?
    我已经积累了关于 C -> Rust 的 FFI 的知识,所以我想为 Rust 传播做各种事情。


原创声明:本文系作者授权爱码网发表,未经许可,不得转载;

原文地址:https://www.likecs.com/show-308623244.html

相关文章:

  • 2021-05-29
  • 2022-12-23
  • 2022-12-23
  • 2021-06-05
  • 2022-12-23
猜你喜欢
  • 2021-11-12
  • 2021-04-24
  • 2022-12-23
  • 2021-11-03
  • 2022-12-23
  • 2021-06-02
相关资源
相似解决方案