Rust UI开发(三):iced如何打开图片(对话框)并在窗口显示图片?

注:此文适合于对rust有一些了解的朋友
iced是一个跨平台的GUI库,用于为rust语言程序构建UI界面。
在这里插入图片描述

这是一个系列博文,本文是第三篇,前两篇的链接:
1、Rust UI开发(一):使用iced构建UI时,如何在界面显示中文字符
2、Rust UI开发(二):iced中如何为窗口添加icon图标

本篇是系列第三篇,主要关注如何在窗口上显示图片,要在窗口显示一张图片,基本上需要解决两个问题,一是图片文件导入,二是图片文件显示。这两个功能对于其他成熟语言都不是问题,文件对话框和图片渲染都不是难事,但iced是缺少对话框部件的。

所以,就要借助于第三方库,下面我们将针对这两个方面做说明。
实际窗口效果预览:
在这里插入图片描述

一 文件对话框

至少目前为止(iced=0.10)iced中没有集成对话框功能,包括文件对话框、字体、颜色、消息等对话框都没有,但我看到其他支持rust的GUI库如egui、nwg(native-window-gui)等都是有对话框的,当然egui中是用rfd库来实现的。
所以,在本篇中,我们也是利用rfd来实现文件对话框功能。
在这里插入图片描述
rfd是Rusty File Dialogs的简写,是跨平台的rust库,提供打开/保存对话框的功能。
rfd的官方代码:

use rfd::FileDialog;let files = FileDialog::new().add_filter("text", &["txt", "rs"]).add_filter("rust", &["rs", "toml"]).set_directory("/").pick_file();

使用起来也很简单,在你的项目的Cargo.toml中添加依赖:

rfd="0.12.1"

然后在main.rs中导入:

use rfd::FileDialog;

需要注意的是,FileDialog.pickfile()函数返回的是一个枚举类型Option,里面的数据就是文件的路径。
所以,我们可以使用Some来返回此路径。

 if let Some(file)=FileDialog::new().set_directory("/").add_filter("all", &["*"])                  //添加文件过滤,all是显示所有类型 .add_filter("文本文件(*txt)", &["txt", "rs"])           //只显示文本类型.add_filter("图像文件(*png*jpg*bmp)", &["png","jpg","jpeg","bmp"])          //只显示图像类型.set_title("打开图像").pick_file(){self.iamgepath=file.display().to_string();};

这样我们打开的图像的路径,就赋给了self.imagepath。

二 将图片显示在窗口界面上

我们现在已经得到了图像的路径,那么我们如何将图像显示在窗口上呢?这里需要用到iced提供的image这个功能,它是被定义为iced_widget的一个特性,即Features。Features是Rust中的一个概念,或者是一种机制。以下是rust官方手册关于Features的概念,大家自己理解一下。

  • Cargo “features” provide a mechanism to express conditional compilation and optional dependencies.
  • A package defines a set of named features in the [features] table of Cargo.toml, and each feature can either be enabled or disabled. Features for the package being built can be enabled on the command-line with flags such as --features. Features for dependencies can be enabled in the dependency declaration in Cargo.toml.

本篇说明一下如何使用image这个Features,在你的项目的Cargo.toml文件中,添加了iced依赖后,添加以下语句:

iced.features=["image"]

然后可以在main.rs中导入image:

use iced::widget::{text, button,slider,column,image,container};

另外,我们在本系列第二篇提到过一个第三方的图像库Image,实际上iced中处理图像也用到了这个库,所以我们将Image也添加到依赖中:

image="0.24.7"

为了不混乱iced的image和第三方image,我们在导入第三方image时,如下:

extern crate image as img_image;

当然,as后面的名字,你可以自己随便定义,只要你知道它是用来代替第三方image的“命名空间”即可。
image部件显示图像代码:

image(hd).content_fit(ContentFit::Fill),

此处,image函数的参数是一个Handle,官方关于image的源代码:

/// Creates a new [`Image`].
///
/// [`Image`]: widget::Image
#[cfg(feature = "image")]
pub fn image<Handle>(handle: impl Into<Handle>) -> crate::Image<Handle> {crate::Image::new(handle.into())
}

所以,我们使用时,需要将图像文件转为Handle类型:

 let hd= if cfg!(target_arch = "wasm32") {               //Wasm32是一种基于WebAssembly(Wasm)的32位虚拟机image::Handle::from_path("iced_test/src/img1.png")} else {//image::Handle::from_path("../iced_test/src/img2.jpeg")image::Handle::from_path(img_path)};

如上,使用image-Handle-from_path函数,从图像路径获取image的Handle,然后将此Handle传给image部件即可。

完整代码:

use iced::widget::{text, button,slider,column,row,image,container};
use iced::{Alignment, Element, Length,Sandbox, Settings, ContentFit, alignment};
use iced::window;
use iced::window::icon;
use iced::window::Position;
use iced::Font;
use iced::font::Family;
extern crate image as img_image;
extern crate num_complex;
use rfd::FileDialog;pub fn main() ->iced::Result{//Counter::run(Settings::default())let ff="微软雅黑";//第二种获取rgba图片的方法,利用Image库let img2=img_image::open("../iced_test/src/dota22.png");  let img2_path=match  img2 {Ok(path)=>path,Err(error)=>panic!("error is {}",error),};let img2_file=img2_path.to_rgba8();let ico2=icon::from_rgba(img2_file.to_vec(), 64, 64);let ico2_file=match ico2{Ok(file)=>file,Err(error)=>panic!("error is {}",error),};Counter::run(Settings { window:window::Settings{                    //设置窗口尺寸和位置及图标size:(800,600),position:Position::Specific(100, 40),icon:Some(ico2_file),..window::Settings::default()},default_font:Font{                         //设置UI界面的显示字体family:Family::Name(ff),..Font::DEFAULT},..Settings::default()})
}pub struct Counter{srcimgpath:String,destimgpath:String,slivalue:f32,
}#[derive(Debug, Clone,Copy)]
pub enum Message {OpenimgPressed,SaveimgPressed,SliderChanged(f32),
}impl Sandbox for Counter {type Message = Message;fn new() -> Self {let path=String::new();Self { srcimgpath: path.to_string(),            //to_string()类似于clonedestimgpath:path.to_string(),slivalue:0.0}}fn title(&self) -> String {String::from("iced_UI演示")}fn update(&mut self, message: Message) {match message {Message::OpenimgPressed => {if let Some(file)=FileDialog::new().set_directory("D:\\008 rustpro\\iced_test\\src").add_filter("all", &["*"])                  //添加文件过滤,all是显示所有类型 .add_filter("文本文件(*txt)", &["txt", "rs"])           //只显示文本类型.add_filter("图像文件(*png*jpg*bmp)", &["png","jpg","jpeg","bmp"])          //只显示图像类型.set_title("打开图像").pick_file(){self.srcimgpath=file.display().to_string();};//println!("{:?}",file);}Message::SaveimgPressed=> {self.destimgpath="".to_string();}Message::SliderChanged(vl)=>{self.slivalue=vl;}}}fn view(&self) -> Element<Message> {let img_path=&self.srcimgpath;let hd= if cfg!(target_arch = "wasm32") {               //Wasm32是一种基于WebAssembly(Wasm)的32位虚拟机image::Handle::from_path("iced_test/src/img1.png")} else {//image::Handle::from_path("../iced_test/src/img2.jpeg")image::Handle::from_path(img_path)};// let hd2= if cfg!(target_arch = "wasm32") {               //Wasm32是一种基于WebAssembly(Wasm)的32位虚拟机//     image::Handle::from_path("iced_test/src/img1.png")// } else {//     image::Handle::from_path(img_path)// };//println!("hd is :{:?}",hd);container(column![row![//btn1button(text("打开图像").horizontal_alignment(alignment::Horizontal::Center).vertical_alignment(alignment::Vertical::Center).size(15)).on_press(Message::OpenimgPressed).padding(4),//btn2button(text("保存图像").horizontal_alignment(alignment::Horizontal::Center).vertical_alignment(alignment::Vertical::Center).size(15)).on_press(Message::SaveimgPressed).padding(4),].spacing(10).padding(10).align_items(Alignment::Start),//text:source image pathtext(format!("原图像路径:{:?}",self.srcimgpath)).size(15).horizontal_alignment(alignment::Horizontal::Center).vertical_alignment(alignment::Vertical::Center),row![text("图像尺寸调整:").size(15),//sliderslider(0.0..=100.0, self.slivalue, Message::SliderChanged).step(0.01).width(200),].spacing(20),//text:dest image pathtext(&self.destimgpath).size(15),row![image(hd).content_fit(ContentFit::Fill),//image(hd2).width(Length::Fixed(100.0)).height(Length::Fixed(100.0)).content_fit(ContentFit::Fill)].spacing(10).padding(10)].spacing(10)       .padding(30).align_items(Alignment::Start)).into()}
}

以上代码中,不仅包含本篇涉及的内容,也包含前2篇中涉及的内容。

动态演示图:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/206513.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言进阶之笔试题详解(2)

前言 这里的内容包括二维数组笔试题和指针笔试题&#xff0c;供给读者对这部分知识进行加深和巩固。 ✨ 猪巴戒&#xff1a;个人主页✨ 所属专栏&#xff1a;《C语言进阶》 &#x1f388;跟着猪巴戒&#xff0c;一起学习C语言&#x1f388; 目录 前言 笔试题 二维数组 题目…

VR Interaction Framework2.0使用

1 按键 &#xff0c;比如按压下手柄的B键 if (InputBridge.Instance.BButtonDown){print("kkkkkkbbbbb456");} 2抓取某个物体&#xff0c;那么就在要抓取的那个物体上加一些组件&#xff0c;特别是Grabble Unity Events 其中UIExAmple为XR Demo自带的 UI wer:我挂的…

中国毫米波雷达产业分析4——毫米波雷达企业介绍

一、矽典微 &#xff08;一&#xff09;公司简介 矽典微致力于实现射频技术的智能化&#xff0c;专注于研发高性能无线技术相关芯片&#xff0c;产品广泛适用于毫米波传感器、下一代移动通信、卫星通信等无线领域。 整合自身在芯片、系统、软件、算法等领域的专业能力&#xf…

【JavaEE】多线程 -- 死锁问题

目录 1. 问题引入 2.死锁问题的概念和原因 3. 解决死锁问题 1. 问题引入 在学习死锁之前, 我们先观察下面的代码能否输出正确的结果: 运行程序, 能正常输出结果: 这个代码只管上看起来, 好像是有锁冲突的, 此时的 locker 对象已经是加锁的状态, 在尝试对 locker 加锁, 不应该…

Ubuntu下载离线安装包

旧版Ubuntu下载地址 https://old-releases.ubuntu.com/releases/ 下载离线包 sudo apt-get --download-only -odir::cache/ncayu install net-tools下载snmp离线安装包 sudo apt-get --download-only -odir::cache/root/snmp install snmp snmpd snmp-mibs-downloadersudo a…

unity Terrain 性能问题

在实践过程中unity发生进入场景GPU爆显存的情况&#xff0c;经过调查发现是使用Terrain造成的问题&#xff0c;这个问题在使用一个Terrain的时候并不会发生&#xff0c;但是在使用多个时会发生。 似乎在使用过程中Terrain会直接把Terrain的整个地图加载&#xff0c;造成移动设…

Ubuntu+Tesla V100环境配置

系统基本信息 nvidia-smi’ nvidia-smi 470.182.03 driver version:470.182.03 cuda version: 11.4 查看系统体系结构 uname -aUTC 2023 x86_64 x86_64 x86_64 GNU/Linux 下载miniconda https://mirrors.tuna.tsinghua.edu.cn/anaconda/miniconda/?CM&OA https://mi…

Dockerfile讲解

Dockerfile 1. 构建过程解析2. Dockerfile常用保留字指令3. 案例3.1. 自定义镜像mycentosjava83.2. 虚悬镜像 4. Docker微服务实战 dockerfile是用来构建docker镜像的文本文件&#xff0c;是由一条条构建镜像所需的指令和参数构成的脚本。 dockerfile定义了进程需要的一切东西&…

[蓝桥杯习题]———位运算、判断二进制1个数

⭐Hello!这里是欧_aita的博客。 ⭐今日语录&#xff1a;行动胜过一切。 ⭐个人主页&#xff1a;欧_aita ψ(._. )>⭐个人专栏&#xff1a; 数据结构与算法&#xff08;内含蓝桥杯习题&#xff09; MySQL数据库 位运算 位运算位运算的定义简单运用 实战刷题题目思路代码实现声…

flutter,uni-app开发调试ios

一、申请ios开发者账号 二、ios开发者配置 ios 开发者需要配置的地方 https://developer.apple.com/account/resources/certificates/list Certificates&#xff08;证书&#xff09;: 作用&#xff1a; 证书用于对应用程序和开发者进行身份验证&#xff0c;确保安全性和可…

mac截图Snagit 中文介绍

1.超越普通的屏幕截图 TechSmith Snagit 是唯一具有内置高级图像编辑和屏幕录制功能的屏幕捕获软件。因此&#xff0c;您可以在一个程序中轻松创建高质量的图像和视频。 2.最后&#xff0c;屏幕捕获软件可以完成您所做的一切 快速解释一个过程如果您正在努力清楚地沟通&…

2023 年 IntelliJ IDEA下载、安装教程,附详细图文

大家好&#xff0c;今天为大家带来的是 2023年 IntelliJ IDEA 下载、安装教程&#xff0c;超详细的图文教程&#xff0c;亲测可用。 文章目录 1 IDEA 下载2 IDEA 安装3 IDEA 使用4 快捷键新手必须掌握&#xff1a;Ctrl&#xff1a;Alt&#xff1a;Shift&#xff1a;Ctrl Alt&a…

STM32CubeIDE(CUBE-MX hal库)----定时器

系列文章目录 STM32CubeIDE(CUBE-MX hal库)----初尝点亮小灯 STM32CubeIDE(CUBE-MX hal库)----按键控制 STM32CubeIDE(CUBE-MX hal库)----串口通信 文章目录 系列文章目录前言一、定时器二、使用步骤三、HAL库实验代码三、标准库代码 前言 STM32定时器是一种多功能外设&#…

【MATLAB】异常数据识别

基于分位数的异常点识别 首先&#xff0c;给定了一个原始数据序列x。然后&#xff0c;计算了序列x的上四分位数和下四分位数&#xff0c;并根据这两个值计算了异常点的阈值。上四分位数减去1.5倍的四分位数范围得到异常值下界&#xff0c;下四分位数加上1.5倍的四分位数范围得…

Selenium介绍及基本使用方法

Selenium是一个开源、免费、简单、灵活&#xff0c;对Web浏览器支持良好的自动化测试工具&#xff0c;在UI自动化、爬虫等场景下是十分实用的&#xff0c;能够熟练掌握并使用Selenium工具可以大大的提高效率。 Selenium简介 Selenium支持多平台、多浏览器、多语言去实现自动化…

【Qt绘图】之绘制坦克

使用绘图事件&#xff0c;绘制坦克。 效果 效果很逼真&#xff0c;想象力&#xff0c;有没有。 示例 代码像诗一样优雅&#xff0c;有没有。 包含头文件 #include <QApplication> #include <QWidget> #include <QPainter>绘制坦克类 class TankWidge…

【docker系列】docker实战之部署SpringBoot项目

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

Docker篇之利用docker搭建ftp服务器可实现多用户上传

一、前言 场景&#xff1a;公司需要搭建FTP服务器&#xff0c;供内网之前可以互相传递数据&#xff0c;安全稳定&#xff0c;需要满足开通多个账号&#xff0c;每个用户上传的文件有自己对应的文件目录。 这里建议&#xff1a;用户目录Disk尽量大一点&#xff0c;避免因为空间不…

低代码平台在数字化转型过程中的定位

内容来自演讲&#xff1a;郭昊东 | 上海外服 | 流程分析工程师 摘要 本文介绍了外服集团的 IT 共享中心在低代码平台应用开发方面的实践经验。他们选择低代码平台的原因包括开发成本低、快速看到实际产品以及能够解决数据孤岛和影子 IT 等问题。他们在应用开发中面临的挑战包括…

android shape绘制半圆

<?xml version"1.0" encoding"utf-8"?><shape xmlns:android"http://schemas.android.com/apk/res/android"android:shape"rectangle"><sizeandroid:width"20dp"android:height"10dp" /><…