图形界面不难吗?
虽然我是初学者,但我觉得一旦成为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 按钮从相机接收图像数据并显示获取的图像。
(图片)
材料
- nodeJS
- nodeJS 的包管理器(似乎推荐使用纱线)
- 可以捕获图像的任何物理对象
试着做
您可以在
yarn create tauri-app开始一个项目。
设置应用名称、标题和网页前端框架。我选择香草是因为我没有做任何花哨的东西。
我喜欢 CUI 完成所有设置的事实。
安装完成后
键入这三行似乎更好,所以键入它们。
您的应用程序将以开发模式运行。现在剩下的就是添加到此。
显示的 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))
与 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>您现在应该能够看到图像。每次按下按钮时,图像都会更新。
如果要做实时处理,是否需要WebRTC之类的技术?
即使在发布版本中,我也觉得响应不如原生 GUI。题外话
Opencv的VideoCapture只读取UVC相机,所以要使用工业相机,需要读取SDK并获取RGB8格式数组和图像大小。
好在opencv-rs有Mat::from_slice,所以我可以管理。也许 ndarray 板条箱更充实?
我已经积累了关于 C -> Rust 的 FFI 的知识,所以我想为 Rust 传播做各种事情。
原创声明:本文系作者授权爱码网发表,未经许可,不得转载;
原文地址:https://www.likecs.com/show-308623244.html