<Rust><iced>基于rust使用iced库构建GUI实例:动态改变主题色

news2025/1/19 3:45:07

前言
本专栏是Rust实例应用。

环境配置
平台:windows
软件:vscode
语言:rust
库:iced、iced_aw

概述
本篇构建了这样的一个实例,可以动态修改UI的主题,通过菜单栏来选择预设的自定义主题和官方主题,以及实时修改rgba色彩来动态调整主题色。
UI图示:
在这里插入图片描述
如上图,本实例是一个简单的应用,是利用菜单栏来选择窗口的主题色,可以选择预设值,也可以选择自定义值,还可以动态调整:
在这里插入图片描述

本篇内容:
1、动态调整主题色

程序结构介绍

本篇涉及到的crate有iced、iced_aw、image、rfd等,详细看toml文件:

[package]
name = "img-convert"
version = "0.1.0"
edition = "2021"

[dependencies]

iced={version ="0.12.1",features = ["svg","canvas","image","multi-window"]}
iced_widget={version = "0.12.3"}
iced_aw={version = "0.9.3",features = ["cupertino"]}

image={version = "0.25.1",features = []}

rfd={version ="0.14.1"}

文件夹结构:
在这里插入图片描述
其中img文件夹提供了UI所需的各种图片:
在这里插入图片描述
本篇所涉及的内容,有一些是公用的,如菜单栏设置、样式设置等,本篇会讲的详细些,后续篇章涉及这些基础内容,就不再赘述。

先说菜单栏的构建的,关于菜单栏的使用,在之前的部件介绍专栏已经介绍过:
RustGUI学习(iced/iced_aw)之扩展小部件(十六):如何使用菜单menu部件来创建菜单栏?
但之前只是简单说了如何使用menu,本篇将详细介绍菜单栏的构建函数。
在这里插入图片描述
如图,菜单的设置,是在一个单独的mod文件中,并没有放在main.rs中,主要是为了方便编写,如果都写在主函数中,显得太拥挤了,也不方便查看。
在menuset.rs中,我们将构建以下函数:
在这里插入图片描述
我们来分别看一下,其中,create_menubar函数,顾名思义,是创建菜单栏主bar的函数,如下:

///
/// 创建一个menu bar
/// 
pub fn create_menubar<'a,Message,Theme,Renderer>(
    menu:Vec<Item<'a,Message,Theme,Renderer>>,
    style:iced_aw::style::menu_bar::MenuBarStyle,
)->MenuBar<'a,Message,Theme,Renderer>
where
    Theme:iced_aw::menu::StyleSheet+iced_aw::style::menu_bar::StyleSheet,
    Renderer:iced::advanced::Renderer,<Theme as iced_aw::menu::StyleSheet>::Style: From<MenuBarStyle>
{   
    MenuBar::new(menu).spacing(4.0).width(Length::Fill).height(40).padding(4)
                            .draw_path(menu::DrawPath::Backdrop)
                            .style(style)
}

通过传入的menu项,返回一个MenuBar部件,传入参数中还包括自定义的style。关于函数的具体代码就不赘述了,这在之前的部件专栏博文中有说明。

接下来说下菜单项的构建函数,有两种,一个是不带子项的,一个是带子项的。
menu无子项:

///
/// 创建一个menu无子项
/// 
pub fn menu_no_sub<'a,Message:'a,Theme,Renderer>(
    label:&'a str,
    msg:Message,
)->Item<'a,Message,Theme,Renderer>
where
    Theme:'a+iced_aw::menu::StyleSheet+button::StyleSheet+text::StyleSheet,
    Renderer: 'a+iced::advanced::Renderer+iced::advanced::text::Renderer,
            <Theme as iced_widget::button::StyleSheet>::Style: From<iced::theme::Button>,Message: std::clone::Clone
{   

        let btn:Button<Message,Theme,Renderer>=menubtn_normal(label, msg,176,Horizontal::Left);
        Item::new(btn)

    
}

可以看到,很简单,就是返回一个Item项,其中菜单button的文本和消息为自定义输入。

menu有子项

///
/// 创建一个menu有子项
/// 
pub fn menu_with_sub<'a,Message:'a,Theme,Renderer>(
    label:&'a str,
    msg:Message,
    arrow:&'a str,
    sub:Vec<Item<'a,Message,Theme,Renderer>>
)->Item<'a,Message,Theme,Renderer>
where
    Theme:'a+iced_aw::menu::StyleSheet+button::StyleSheet+text::StyleSheet+svg::StyleSheet,
    Renderer: 'a+iced::advanced::Renderer+iced::advanced::text::Renderer+iced::advanced::svg::Renderer,
                Message: std::clone::Clone,<Theme as iced_widget::button::StyleSheet>::Style: From<iced::theme::Button>
  
{   
    let item=menubtn_arrow(label, msg, arrow,176);
    let menu=Menu::new(sub).max_width(180.0).spacing(5.0).offset(3.0);


    Item::with_menu(item, menu)
}

带子项的menu稍微复杂些,其中Item的项包括了button以及一个箭头(右向,svg格式):
在这里插入图片描述
svg构成:

<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1715601105402" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3106" xmlns:xlink="http://www.w3.org/1999/xlink" width="16" height="16"><path d="M256 102.4v819.2l512-409.6L256 102.4z" fill="#333333" p-id="3107"></path></svg>

也可以去一些提供向量图标的网站下载。

通常,菜单项使用的都是button加文字,因为菜单就是用来点击的,但是也可以使用其他部件,如滑动条,本篇为了方便动态调整颜色值,添加了slider构建的menu:

///
/// 创建一个menu无子项(slider样式)
/// 
pub fn menu_no_sub_slider<'a,Message,Theme,Renderer>(
    label:&'a str,
    msg:impl Fn(f32) -> Message + 'a,
    slidervalue:f32,
    themecolor:Color,
)->Item<'a,Message,Theme,Renderer>
where
    Theme:'a+iced_aw::menu::StyleSheet+iced_widget::slider::StyleSheet+iced_widget::text::StyleSheet,
    Renderer: 'a+iced::advanced::Renderer+iced::advanced::text::Renderer,
    Message: std::clone::Clone+'a,<Theme as iced_widget::slider::StyleSheet>::Style: From<iced::theme::Slider>,
    <Theme as iced_widget::text::StyleSheet>::Style: From<iced::theme::Text>
{   

    let style1=iced::theme::Slider::Custom(Box::new(MySliderStyle{color:themecolor}));
    let mut r1=0.0;
    let mut g1=0.0;
    let mut b1=0.0;
    let mut a1=1.0;
    if themecolor.r<=0.1 || themecolor.g<=0.1 || themecolor.b<=0.1{
        r1=0.9;
        g1=0.9;
        b1=0.9;
    }else if themecolor.r>=0.8 || themecolor.g>=0.8 || themecolor.b>=0.8{
        r1=0.02;
        g1=0.02;
        b1=0.02;
    }
    else{
        r1=themecolor.r;
        g1=themecolor.g;
        b1=themecolor.b;
    }

    let style2=iced::theme::Text::Color(Color::from_rgba(r1, g1, b1, a1));
    let text0=text(label).width(20).size(12).style(style2);
    let slider=slider(0.0..=1.0,slidervalue, msg).step(0.01).width(100).style(style1);
    let text1=text(format!("{}",slidervalue)).width(30).size(12).style(style2);
    let row1=row![
        text0,
        horizontal_space().height(10),
        slider,
        horizontal_space().height(10),
        text1
        ].align_items(Alignment::Center).spacing(5);
    Item::new(row1)
}

上面的函数,菜单项中添加的是slider,其中slider的样式可以根据UI的背景色调整而调整,主要是为了背景色调整过程菜单项的可视性。
还有两个函数是构建菜单项button的,之所以将button项单独使用函数构建,也是为了方便修改参数。这两个函数不再细说,但代码会在后面全部贴出来。

菜单项的构建就完成了,然后在主函数里调用菜单项:

 let arrowsvg="..\\img-convert\\img\\arrow\\arrow_right_16.svg";
        let wj_open=menuset::menu_no_sub("打开",Message::WJ(menuset::WJMessage::Open));
        // let wj_new_mode1=menuset::menu_no_sub("格式1",Message::WJ(menuset::WJMessage::Open) );
        // let wj_new_mode2=menuset::menu_no_sub("格式2",Message::WJ(menuset::WJMessage::Open) );
        let wj_new=menuset::menu_no_sub("新建", Message::WJ(menuset::WJMessage::New));
        let wj_save=menuset::menu_no_sub("保存",Message::WJ(menuset::WJMessage::Save));
        let wj_close=menuset::menu_no_sub("关闭",Message::WJ(menuset::WJMessage::Close));
        let wj_main=menuset::menu_main("文件", Message::WJ(menuset::WJMessage::WenJian), 

通常,菜单项就是菜单栏中添加主菜单项,点击主菜单项,下拉子项,子项还可以附带子项,如上面的代码,是主菜单为“文件”的菜单项,下拉菜单为【打开、新建、保存、关闭】,很常见的对吧。
在这里插入图片描述
注意,上述代码中,调用的函数,其中menuset为mod,需要提前导入:

mod menuset;

以此类推,如果你要构建其他菜单项,按照样式填写即可,当然,其中消息需要自己构建,可以直接写在menuset模块中:

#[derive(Debug,Clone)]
pub enum WJMessage{
    WenJian,
    Open,
    Close,
    New,
    Save,
}

注意要使用pub关键字,然后其他文件里调用。
在这里插入图片描述
如上图,主函数调用menuset的菜单项enum。

以上,菜单项的设置就完成了,样式如下:
在这里插入图片描述
在这里插入图片描述
示例只添加了三个主菜单项,如果你想要更多的,自行添加即可。
不过,需要注意的是,本文没有为菜单添加快捷键功能,这涉及到监控键盘的行为,会在后面的高级一点的示例中说到。

下面说下主题修改涉及的函数,即uitheme.rs。
在这里插入图片描述
本模块中,主要包含了一个是自定义预设值,T1、T2、T3,实现的函数是theme_name。
一个是动态调整主题色,实现的函数是get_color。
至于官方预设的颜色值,就无需多次重构,直接使用即可。

来看下自定义预设主题,其实现代码如下:

impl UITheme{
    pub fn theme_name(&self) -> Theme{
        match self{
            UITheme::T1 => {
                let p1=Palette{
                        background:iced::Color::from_rgba(0.0, 0.65, 0.6, 0.7),
                        text:Color::BLACK,
                        primary:Color::BLACK,
                        success:Color::BLACK,
                        danger:Color::BLACK,
                };
                let g1=Extended{
                    background:Background{
                        base:Pair{color:Color::from_rgba(0.1, 0.7, 0.7, 0.8),text:Color::BLACK},
                        weak:Pair{color:Color::from_rgba(0.1, 0.7, 0.7, 0.8),text:Color::BLACK},
                        strong:Pair{color:Color::from_rgba(0.1, 0.7, 0.7, 0.8),text:Color::BLACK},
                    },
                    primary:Primary{
                        base:Pair{color:Color::from_rgba(0.1, 0.7, 0.7, 0.8),text:Color::BLACK},
                        weak:Pair{color:Color::from_rgba(0.1, 0.7, 0.7, 0.8),text:Color::BLACK},
                        strong:Pair{color:Color::from_rgba(0.1, 0.7, 0.7, 0.8),text:Color::BLACK},
                    },
                    secondary:Secondary{
                        base:Pair{color:Color::from_rgba(0.1, 0.7, 0.7, 0.8),text:Color::BLACK},
                        weak:Pair{color:Color::from_rgba(0.1, 0.7, 0.7, 0.8),text:Color::BLACK},
                        strong:Pair{color:Color::from_rgba(0.1, 0.7, 0.7, 0.8),text:Color::BLACK},
                    },
                    success:Success{
                        base:Pair{color:Color::from_rgba(0.1, 0.7, 0.7, 0.8),text:Color::BLACK},
                        weak:Pair{color:Color::from_rgba(0.1, 0.7, 0.7, 0.8),text:Color::BLACK},
                        strong:Pair{color:Color::from_rgba(0.1, 0.7, 0.7, 0.8),text:Color::BLACK},
                    },
                    danger:Danger{
                        base:Pair{color:Color::from_rgba(0.1, 0.7, 0.7, 0.8),text:Color::BLACK},
                        weak:Pair{color:Color::from_rgba(0.1, 0.7, 0.7, 0.8),text:Color::BLACK},
                        strong:Pair{color:Color::from_rgba(0.1, 0.7, 0.7, 0.8),text:Color::BLACK},
                    },
                    is_dark:false,
                };
                let cus1=Arc::new(iced::theme::Custom::new("t1".to_string(),p1));
                let cus2=Arc::new(iced::theme::Custom::with_fn("t1".to_string(), p1, |_|g1));
       
                iced::Theme::Custom(cus1)
            }
            UITheme::T2 => {
                let p1=Palette{
                    //background:iced::Color::from_rgba(0.0, 0.85, 0.8, 0.8),
                    background:Color::from_linear_rgba(0.0, 0.5, 0.6, 0.8),
                    text:Color::BLACK,
                    primary:Color::BLACK,
                    success:Color::BLACK,
                    danger:Color::BLACK,
                };
                let cus1=Arc::new(iced::theme::Custom::new("t1".to_string(),p1));
   
                iced::Theme::Custom(cus1)
            },
            UITheme::T3 => {
                let p1=Palette{
                    background:iced::Color::from_rgba(0.0, 0.85, 0.8, 0.8),
                    text:Color::BLACK,
                    primary:Color::BLACK,
                    success:Color::BLACK,
                    danger:Color::BLACK,
                };
                let cus1=Arc::new(iced::theme::Custom::new("t1".to_string(),p1));
    
                iced::Theme::Custom(cus1)
            },
        }
    }

}

需要注意的是,本文的代码只是为了演示,一些参数设置只要达到效果即可,所以,并非所有涉及的参数都做了修改。如上代码,我们只是简单的构建了三个自定义样式T1、T2、T3,然后为每个主题都设置自己的颜色,通过菜单选择相应的主题时,获得自定义的颜色效果:
在这里插入图片描述
再来看下动态调整实现:

pub struct UIThemeColor{
    pub color:Color,
}

impl UIThemeColor {
    pub fn get_color(&self) -> Theme {

        let p1=Palette{
            background:self.color,
            text:Color::BLACK,
            primary:Color::BLACK,
            success:Color::BLACK,
            danger:Color::BLACK,
        };
        let cus1=Arc::new(iced::theme::Custom::new("t1".to_string(),p1));

        iced::Theme::Custom(cus1)
}
}

代码不难,我们构建一个结构体,包含参数color,用于自定义输入,然后实现函数get_color,用于动态调整时,传入外面的颜色值,函数内部使用此color值,来构建自定义的Theme,以此实现主题色的动态调整:
在这里插入图片描述

完整代码

menuset.rs

use iced::advanced::widget::Text;
use iced::alignment::Horizontal;
use iced::widget::{button, text,row,svg,horizontal_space,slider,};
use iced::{Alignment, Background, Border, Color, Length, Theme};
use iced_aw::menu::{self, Item, Menu, MenuBar};
use iced::widget::{Button, Row};
use iced_aw::style::menu_bar::MenuBarStyle;
use iced::widget::slider::{Rail,HandleShape};



#[derive(Debug,Clone)]
pub enum WJMessage{
    WenJian,
    Open,
    Close,
    New,
    Save,
}
#[derive(Debug,Clone)]
pub enum GJMessage{
    GongJv,
    T1,
    T2,
    T3,
}

#[derive(Debug,Clone)]
pub enum GYMessage{
    GuanYu,
    GY,
    BZ,
    GX,
}

///
/// 创建一个menu bar
/// 
pub fn create_menubar<'a,Message,Theme,Renderer>(
    menu:Vec<Item<'a,Message,Theme,Renderer>>,
    style:iced_aw::style::menu_bar::MenuBarStyle,
)->MenuBar<'a,Message,Theme,Renderer>
where
    Theme:iced_aw::menu::StyleSheet+iced_aw::style::menu_bar::StyleSheet,
    Renderer:iced::advanced::Renderer,<Theme as iced_aw::menu::StyleSheet>::Style: From<MenuBarStyle>
{   
    MenuBar::new(menu).spacing(4.0).width(Length::Fill).height(40).padding(4)
                            .draw_path(menu::DrawPath::Backdrop)
                            .style(style)
}

///
/// 创建一个menu主项
/// 
pub fn menu_main<'a,Message:'a,Theme,Renderer>(
    label:&'a str,
    msg:Message,
    sub:Vec<Item<'a,Message,Theme,Renderer>>
)->Item<'a,Message,Theme,Renderer>
where
    Theme:'a+iced_aw::menu::StyleSheet+button::StyleSheet+text::StyleSheet+svg::StyleSheet,
    Renderer: 'a+iced::advanced::Renderer+iced::advanced::text::Renderer+iced::advanced::svg::Renderer,
    Message: std::clone::Clone,
    <Theme as iced_widget::button::StyleSheet>::Style: From<iced::theme::Button>
{   
    let item: Button<Message, Theme, Renderer>=menubtn_normal(label, msg,60,Horizontal::Center);
    let menu: Menu<Message, Theme, Renderer>=Menu::new(sub).max_width(180.0).spacing(5.0).offset(5.0);

    Item::with_menu(item, menu)
}

///
/// 创建一个menu无子项(slider样式)
/// 
pub fn menu_no_sub_slider<'a,Message,Theme,Renderer>(
    label:&'a str,
    msg:impl Fn(f32) -> Message + 'a,
    slidervalue:f32,
    themecolor:Color,
)->Item<'a,Message,Theme,Renderer>
where
    Theme:'a+iced_aw::menu::StyleSheet+iced_widget::slider::StyleSheet+iced_widget::text::StyleSheet,
    Renderer: 'a+iced::advanced::Renderer+iced::advanced::text::Renderer,
    Message: std::clone::Clone+'a,<Theme as iced_widget::slider::StyleSheet>::Style: From<iced::theme::Slider>,
    <Theme as iced_widget::text::StyleSheet>::Style: From<iced::theme::Text>
{   

    let style1=iced::theme::Slider::Custom(Box::new(MySliderStyle{color:themecolor}));
    let mut r1=0.0;
    let mut g1=0.0;
    let mut b1=0.0;
    let mut a1=1.0;
    if themecolor.r<=0.1 || themecolor.g<=0.1 || themecolor.b<=0.1{
        r1=0.9;
        g1=0.9;
        b1=0.9;
    }else if themecolor.r>=0.8 || themecolor.g>=0.8 || themecolor.b>=0.8{
        r1=0.02;
        g1=0.02;
        b1=0.02;
    }
    else{
        r1=themecolor.r;
        g1=themecolor.g;
        b1=themecolor.b;
    }

    let style2=iced::theme::Text::Color(Color::from_rgba(r1, g1, b1, a1));
    let text0=text(label).width(20).size(12).style(style2);
    let slider=slider(0.0..=1.0,slidervalue, msg).step(0.01).width(100).style(style1);
    let text1=text(format!("{}",slidervalue)).width(30).size(12).style(style2);
    let row1=row![
        text0,
        horizontal_space().height(10),
        slider,
        horizontal_space().height(10),
        text1
        ].align_items(Alignment::Center).spacing(5);
    Item::new(row1)
}


///
/// 创建一个menu无子项
/// 
pub fn menu_no_sub<'a,Message:'a,Theme,Renderer>(
    label:&'a str,
    msg:Message,
)->Item<'a,Message,Theme,Renderer>
where
    Theme:'a+iced_aw::menu::StyleSheet+button::StyleSheet+text::StyleSheet,
    Renderer: 'a+iced::advanced::Renderer+iced::advanced::text::Renderer,
            <Theme as iced_widget::button::StyleSheet>::Style: From<iced::theme::Button>,Message: std::clone::Clone
{   

        let btn:Button<Message,Theme,Renderer>=menubtn_normal(label, msg,176,Horizontal::Left);
        Item::new(btn)

    
}

///
/// 创建一个menu有子项
/// 
pub fn menu_with_sub<'a,Message:'a,Theme,Renderer>(
    label:&'a str,
    msg:Message,
    arrow:&'a str,
    sub:Vec<Item<'a,Message,Theme,Renderer>>
)->Item<'a,Message,Theme,Renderer>
where
    Theme:'a+iced_aw::menu::StyleSheet+button::StyleSheet+text::StyleSheet+svg::StyleSheet,
    Renderer: 'a+iced::advanced::Renderer+iced::advanced::text::Renderer+iced::advanced::svg::Renderer,
                Message: std::clone::Clone,<Theme as iced_widget::button::StyleSheet>::Style: From<iced::theme::Button>
  
{   
    let item=menubtn_arrow(label, msg, arrow,176);
    let menu=Menu::new(sub).max_width(180.0).spacing(5.0).offset(3.0);


    Item::with_menu(item, menu)
}
///
/// 创建一个menu按钮无箭头
/// 
fn menubtn_normal<'a,Message,Theme,Renderer>(
    label:&'a str,
    msg:Message,
    width:u16,
    align:Horizontal,
)->Button<'a,Message,Theme,Renderer>
where
    Theme:'a+iced_aw::menu::StyleSheet+button::StyleSheet+text::StyleSheet,
    Renderer: 'a+iced::advanced::Renderer+iced::advanced::text::Renderer,
                <Theme as iced_widget::button::StyleSheet>::Style: From<iced::theme::Button>
{   
    
    let tt=text(label).size(15)
                            .vertical_alignment(iced::alignment::Vertical::Center)
                            .horizontal_alignment(align);
    button(tt).width(width).height(30)
                        .on_press(msg)
                        .style(iced::theme::Button::Custom(Box::new(MenuButtonStyle)))
}

///
/// 创建一个menu按钮有箭头
/// 
fn menubtn_arrow<'a,Message:'a,Theme,Renderer>(
    label:&'a str,
    msg:Message,
    arrow:&'a str,
    width:u16,
)->Button<'a,Message,Theme,Renderer>
    where
        Theme:'a+iced_aw::menu::StyleSheet+button::StyleSheet+text::StyleSheet+svg::StyleSheet,
        Renderer: 'a+iced::advanced::Renderer+iced::advanced::text::Renderer+iced::advanced::svg::Renderer,
                <Theme as iced_widget::button::StyleSheet>::Style: From<iced::theme::Button>
{
    let tt:Text<Theme,Renderer>=text(label).size(14)
                                    .vertical_alignment(iced::alignment::Vertical::Center)
                                    .horizontal_alignment(iced::alignment::Horizontal::Center);
    let arrow_svg=svg(svg::Handle::from_path(arrow)).width(16).height(16);
    let rr:Row<Message,Theme,Renderer>=row![
        tt,
        horizontal_space().height(20),
        arrow_svg,
    ].spacing(10)
    .align_items(iced::Alignment::Center)
    .into();
    button(rr).width(width).height(30)
                        .on_press(msg)
                        .style(iced::theme::Button::Custom(Box::new(MenuButtonStyle)))
}
struct MenuButtonStyle;
impl button::StyleSheet for MenuButtonStyle{
    type Style = iced::Theme;
    fn active(&self, style: &Self::Style) -> button::Appearance {
        let backcolor=Color::from_rgb8(167, 218, 220);
        button::Appearance {
            text_color:Color::BLACK,
            background:Some(Background::Color(backcolor)),
            border:Border{
                radius:[4.0;4].into(),
                ..Default::default()
            },
            ..Default::default()
        }
    }
    fn pressed(&self, style: &Self::Style) -> button::Appearance {
        let backcolor=Color::from_rgb8(16, 137, 177);
        button::Appearance {
            text_color:Color::BLACK,
            background:Some(Background::Color(backcolor)),
            border:Border{
                radius:[4.0;4].into(),
                ..Default::default()
            },
            ..Default::default()
        }
    }
    fn hovered(&self, style: &Self::Style) -> button::Appearance {
        let backcolor=Color::from_rgb8(0, 164, 230);
        button::Appearance {
            text_color:Color::BLACK,
            background:Some(Background::Color(backcolor)),
            border:Border{
                radius:[4.0;4].into(),
                ..Default::default()
            },
            ..Default::default()
        }
    }
    fn disabled(&self, style: &Self::Style) -> button::Appearance {  
        let backcolor=Color::from_rgb8(0, 0, 100);    
        button::Appearance {
            text_color:Color::BLACK,
            background:Some(Background::Color(backcolor)),
            border:Border{
                radius:[4.0;4].into(),
                ..Default::default()
            },
            ..Default::default()
        }
    }
}

pub struct MyMenuBarStyle{
    pub backcolor:Color,
}
impl iced_aw::style::menu_bar::StyleSheet for MyMenuBarStyle {
    type Style = iced::Theme;
    fn appearance(&self, style: &Self::Style) -> iced_aw::style::menu_bar::Appearance {
        let r=self.backcolor.r;
        let g=self.backcolor.g;
        let b=self.backcolor.b;
        let a=self.backcolor.a;
        let color1=Color::from_rgba(r+0.2, g+0.2, b+0.2, a+0.1);
            iced_aw::style::menu_bar::Appearance {
                //bar_background:Background::Color(Color::from_rgb8(177, 244, 251)),
                bar_background:Background::Color(self.backcolor),
                menu_background:Background::Color(color1),
                ..Default::default()
            }
    }
}

struct MySliderStyle{
    color:Color,
}
impl slider::StyleSheet for MySliderStyle { 
    type Style = Theme;
    //激活时外观
    
    fn active(&self, style: &Self::Style) -> slider::Appearance {
        
        let mut r1=0.0;
        let mut g1=0.0;
        let mut b1=0.0;
        let mut a1=0.0;

        if self.color.r<=0.1 && self.color.g<=0.1 && self.color.b<=0.1{
            r1=0.5;
            g1=0.5;
            b1=0.5;
        }else if self.color.r>=0.9 || self.color.g>=0.9 || self.color.b>=0.9{
            r1=0.2;
            g1=0.2;
            b1=0.2;
        }
        else{
            r1=self.color.r;
            g1=self.color.g;
            b1=self.color.b;
        }
        if self.color.a<=0.1{
            a1=0.7;
        }else{
            a1=self.color.a;
        }
        
        slider::Appearance { 
            rail: Rail{
                colors:(Color::from_rgba(r1-0.2, g1-0.2, b1-0.2,a1+0.1),Color::from_rgba(r1+0.2, g1+0.2, b1+0.2,a1+0.1)),
                width:5.0,
                border_radius:[3.0;4].into(),
            }, 
            handle: slider::Handle{
                shape:HandleShape::Rectangle { width: 8, border_radius: [2.0;4].into() },
                color:Color::from_rgba(r1+0.1, g1+0.1,b1+0.1,a1),
                border_width:1.0,
                border_color:Color::BLACK,
            }
        }
    }
    //悬停时外观
    fn hovered(&self, style: &Self::Style) -> slider::Appearance {
        let r1=self.color.r;
        let g1=self.color.g;
        let b1=self.color.b;
        let a1=self.color.a;
        slider::Appearance { 
            rail: Rail{
                colors:(Color::from_rgba(r1+0.1, g1+0.1, b1+0.1,a1),Color::from_rgba(r1-0.1, g1-0.1, b1-0.1,a1)),
                width:5.0,
                border_radius:[3.0;4].into(),
            }, 
            handle: slider::Handle{
                shape:HandleShape::Rectangle { width: 8, border_radius: [2.0;4].into()},
                color:Color::from_rgba(r1+0.2, g1+0.2,b1+0.2,a1),
                border_width:1.0,
                border_color:Color::BLACK,
            }
        }
    }
    //拖拽时外观
    fn dragging(&self, style: &Self::Style) -> slider::Appearance {
        slider::Appearance { 
            rail: Rail{
                colors:(Color::from_rgb8(20, 48, 210),Color::from_rgb8(151, 155, 175)),
                width:5.0,
                border_radius:[3.0;4].into(),
            }, 
            handle: slider::Handle{
                shape:HandleShape::Rectangle { width: 8, border_radius: [2.0;4].into() },
                color:Color::from_rgb8(13, 248,44),
                border_width:1.0,
                border_color:Color::BLACK,
            }
        }
        
    }
}



uitheme.rs

use iced::{theme::{palette::{Background, Danger, Extended, Pair, Primary, Secondary, Success}, Palette}, Color,Theme};
use iced_aw::core::color;
use std::sync::Arc;


pub enum UITheme{
    T1,
    T2,
    T3,
}

impl UITheme{
    pub fn theme_name(&self) -> Theme{
        match self{
            UITheme::T1 => {
                let p1=Palette{
                        background:iced::Color::from_rgba(0.0, 0.65, 0.6, 0.7),
                        text:Color::BLACK,
                        primary:Color::BLACK,
                        success:Color::BLACK,
                        danger:Color::BLACK,
                };
                let g1=Extended{
                    background:Background{
                        base:Pair{color:Color::from_rgba(0.1, 0.7, 0.7, 0.8),text:Color::BLACK},
                        weak:Pair{color:Color::from_rgba(0.1, 0.7, 0.7, 0.8),text:Color::BLACK},
                        strong:Pair{color:Color::from_rgba(0.1, 0.7, 0.7, 0.8),text:Color::BLACK},
                    },
                    primary:Primary{
                        base:Pair{color:Color::from_rgba(0.1, 0.7, 0.7, 0.8),text:Color::BLACK},
                        weak:Pair{color:Color::from_rgba(0.1, 0.7, 0.7, 0.8),text:Color::BLACK},
                        strong:Pair{color:Color::from_rgba(0.1, 0.7, 0.7, 0.8),text:Color::BLACK},
                    },
                    secondary:Secondary{
                        base:Pair{color:Color::from_rgba(0.1, 0.7, 0.7, 0.8),text:Color::BLACK},
                        weak:Pair{color:Color::from_rgba(0.1, 0.7, 0.7, 0.8),text:Color::BLACK},
                        strong:Pair{color:Color::from_rgba(0.1, 0.7, 0.7, 0.8),text:Color::BLACK},
                    },
                    success:Success{
                        base:Pair{color:Color::from_rgba(0.1, 0.7, 0.7, 0.8),text:Color::BLACK},
                        weak:Pair{color:Color::from_rgba(0.1, 0.7, 0.7, 0.8),text:Color::BLACK},
                        strong:Pair{color:Color::from_rgba(0.1, 0.7, 0.7, 0.8),text:Color::BLACK},
                    },
                    danger:Danger{
                        base:Pair{color:Color::from_rgba(0.1, 0.7, 0.7, 0.8),text:Color::BLACK},
                        weak:Pair{color:Color::from_rgba(0.1, 0.7, 0.7, 0.8),text:Color::BLACK},
                        strong:Pair{color:Color::from_rgba(0.1, 0.7, 0.7, 0.8),text:Color::BLACK},
                    },
                    is_dark:false,
                };
                let cus1=Arc::new(iced::theme::Custom::new("t1".to_string(),p1));
                let cus2=Arc::new(iced::theme::Custom::with_fn("t1".to_string(), p1, |_|g1));
       
                iced::Theme::Custom(cus1)
            }
            UITheme::T2 => {
                let p1=Palette{
                    //background:iced::Color::from_rgba(0.0, 0.85, 0.8, 0.8),
                    background:Color::from_linear_rgba(0.0, 0.5, 0.6, 0.8),
                    text:Color::BLACK,
                    primary:Color::BLACK,
                    success:Color::BLACK,
                    danger:Color::BLACK,
                };
                let cus1=Arc::new(iced::theme::Custom::new("t1".to_string(),p1));
   
                iced::Theme::Custom(cus1)
            },
            UITheme::T3 => {
                let p1=Palette{
                    background:iced::Color::from_rgba(0.0, 0.85, 0.8, 0.8),
                    text:Color::BLACK,
                    primary:Color::BLACK,
                    success:Color::BLACK,
                    danger:Color::BLACK,
                };
                let cus1=Arc::new(iced::theme::Custom::new("t1".to_string(),p1));
    
                iced::Theme::Custom(cus1)
            },
        }
    }

}

pub struct UIThemeColor{
    pub color:Color,
}

impl UIThemeColor {
    pub fn get_color(&self) -> Theme {

        let p1=Palette{
            background:self.color,
            text:Color::BLACK,
            primary:Color::BLACK,
            success:Color::BLACK,
            danger:Color::BLACK,
        };
        let cus1=Arc::new(iced::theme::Custom::new("t1".to_string(),p1));

        iced::Theme::Custom(cus1)
}
}

main.rs

#![allow(dead_code)]
#![allow(overflowing_literals)]
//cfg可以实现debug期间无视未使用、未导入等警告信息,但不影响发布后的警告
#![cfg_attr(debug_assertions, allow(dead_code, unused_imports,unused_variables,unused_mut
                                    ,unused_assignments))]
use core::prelude;

use iced::widget::{button, container, slider, text,svg,image,row,column};
use iced::window::{self,Icon};
use iced::{Application, Color, Command, Element, Point, Renderer, Settings, Size, Subscription};
use iced_aw::menu;
use iced_widget::graphics::text::cosmic_text::rustybuzz::ttf_parser::gdef;
use iced_widget::runtime::futures::event;
use rfd::{FileDialog,MessageDialog};
extern crate image as eximage;

mod menuset;
mod uitheme;

struct Example{
    slider_value:f32,
    slider_value2:f32,
    slider_value3:f32,
    slider_value4:f32,
    theme:iced::Theme,
}


#[derive(Debug,Clone)]
enum Message{
    SliderChanged(f32),
    SliderChanged2(f32),
    SliderChanged3(f32),
    SliderChanged4(f32),
    WJ(menuset::WJMessage),
    GJ(menuset::GJMessage),
    GY(menuset::GYMessage),
    GFTheme(iced::Theme),
    MenuNone,
    EventOcu(iced::Event),
}


///
/// 图片转为icon格式
fn image_to_icon(file:& str,w:u32,h:u32,) -> Icon {
    let img=eximage::open(file);
    let img_path=match img{
        Ok(path)=>path,
        Err(e)=>panic!("{}",e),
    };
    let img_file=img_path.to_rgba8();
    let icon=iced::window::icon::from_rgba(img_file.to_vec(), w, h);
    let icon2=match icon{
        Ok(iconfile)=>iconfile,
        Err(e)=>panic!("{}",e),
    };
    icon2
}

fn main() -> iced::Result {
    //Example::run(Settings::default())
    let myfont="微软雅黑";
    let icon=image_to_icon("../img-convert/img/icon1.png", 500, 500);
    Example::run(Settings{
        window:window::Settings{
            size:Size{width:800.0,height:600.0},
            position:window::Position::Specific(Point{x:100.0,y:40.0}),
            icon:Some(icon),
            ..Default::default()
        },
        default_font:iced::Font{
            family:iced::font::Family::Name(myfont),
            ..Default::default()
        },
        ..Default::default()
    })

}

async fn load() -> Result<(),String> {
    Ok(())
}

impl Application for Example {
    type Executor =iced::executor::Default;
    type Message =Message;
    type Theme = iced::Theme;
    type Flags = ();

    fn new(flags: Self::Flags) -> (Self, Command<Self::Message>) {
        
        (Self{
            slider_value:0.5,
            slider_value2:0.5,
            slider_value3:0.5,
            slider_value4:0.8,
            theme:iced::Theme::Light,
            },
        Command::none()
       
        )}
    fn title(&self) -> String {
        String::from("图片格式转换器")
    }

    fn theme(&self) -> Self::Theme {

        self.theme.clone()

    }

    fn update(&mut self, message: Self::Message) -> Command<Self::Message> {
        
       match message{
                Message::SliderChanged(value)=>{
                    self.slider_value=value;
                    let color1=Color::from_rgba(self.slider_value, self.slider_value2,self.slider_value3, self.slider_value4);
                    self.theme=uitheme::UIThemeColor::get_color(&uitheme::UIThemeColor{color:color1});
                }
                Message::SliderChanged2(value)=>{
                    self.slider_value2=value;
                    let color1=Color::from_rgba(self.slider_value, self.slider_value2,self.slider_value3, self.slider_value4);
                    self.theme=uitheme::UIThemeColor::get_color(&uitheme::UIThemeColor{color:color1});
                }
                Message::SliderChanged3(value)=>{
                    self.slider_value3=value;
                    let color1=Color::from_rgba(self.slider_value, self.slider_value2,self.slider_value3, self.slider_value4);
                    self.theme=uitheme::UIThemeColor::get_color(&uitheme::UIThemeColor{color:color1});
                }
                Message::SliderChanged4(value)=>{
                    self.slider_value4=value;
                    let color1=Color::from_rgba(self.slider_value, self.slider_value2,self.slider_value3, self.slider_value4);
                    self.theme=uitheme::UIThemeColor::get_color(&uitheme::UIThemeColor{color:color1});
                }
                Message::WJ(msg)=>{
                    match msg{
                        menuset::WJMessage::New=>{
                            println!("new");
                        }
                        menuset::WJMessage::Open=>{
                            println!("open")
                        }
                        menuset::WJMessage::Close=>{
                            
                           return window::close(window::Id::MAIN)
    
                        }
                        menuset::WJMessage::Save=>{
                            println!("save")
                        }
                        menuset::WJMessage::WenJian=>{
                            println!("wenjian")
                        }
                    }
                }
                Message::GJ(msg)=>{
                    match msg{
                        menuset::GJMessage::GongJv=>{
                            println!("gongjv");
                        }
                        menuset::GJMessage::T1=>{
                            println!("t1");
                            self.theme=uitheme::UITheme::theme_name(&uitheme::UITheme::T1);
                            self.slider_value=self.theme.clone().palette().background.r;
                            self.slider_value2=self.theme.clone().palette().background.g;
                            self.slider_value3=self.theme.clone().palette().background.b;
                            self.slider_value4=self.theme.clone().palette().background.a;
                        }
                        menuset::GJMessage::T2=>{
                            println!("t2");
                            //self.theme=iced::Theme::Custom(Arc::new());
                            let tt=uitheme::UITheme::theme_name(&uitheme::UITheme::T2);
                            self.theme=tt;
                            self.slider_value=self.theme.clone().palette().background.r;
                            self.slider_value2=self.theme.clone().palette().background.g;
                            self.slider_value3=self.theme.clone().palette().background.b;
                            self.slider_value4=self.theme.clone().palette().background.a;
                        }
                        menuset::GJMessage::T3=>{
                            println!("t3");
                            self.theme=uitheme::UITheme::theme_name(&uitheme::UITheme::T3);
                            self.slider_value=self.theme.clone().palette().background.r;
                            self.slider_value2=self.theme.clone().palette().background.g;
                            self.slider_value3=self.theme.clone().palette().background.b;
                            self.slider_value4=self.theme.clone().palette().background.a;
                        }
                    }
                }
                Message::GY(msg)=>{
                    match msg{
                        menuset::GYMessage::GuanYu=>{
                            println!("guanyu");
                        }
                        menuset::GYMessage::GY=>{
                            println!("gy");
                            let res=rfd::MessageDialog::new()
                                    .set_title("关于")
                                    .set_level(rfd::MessageLevel::Info)
                                    .set_description("本软件是基于rust和iced的图像处理软件")
                                    .set_buttons(rfd::MessageButtons::Ok)
                                    .show();
                        }
                        menuset::GYMessage::BZ=>{
                            println!("bz")
                        }
                        menuset::GYMessage::GX=>{
                            println!("gx")
                        }
                    }
                }
                Message::GFTheme(gftheme)=>{
                    self.theme=gftheme;
                    self.slider_value=self.theme.clone().palette().background.r;
                    self.slider_value2=self.theme.clone().palette().background.g;
                    self.slider_value3=self.theme.clone().palette().background.b;
                    self.slider_value4=self.theme.clone().palette().background.a;
                }
                Message::MenuNone=>{
    
                }
                Message::EventOcu(event)=>{
                  
                }
            }
        

        


        Command::none()
    }

    fn subscription(&self) -> Subscription<Self::Message> {
        event::listen().map(Message::EventOcu)
        //Subscription::none()
    }

    fn view(&self) -> Element<'_, Self::Message, Self::Theme, crate::Renderer> {
        let themecolor=self.theme.palette().clone().background;
        //println!("{:?}",themecolor);
        //menu list set
        let arrowsvg="..\\img-convert\\img\\arrow\\arrow_right_16.svg";
        let wj_open=menuset::menu_no_sub("打开",Message::WJ(menuset::WJMessage::Open));
        // let wj_new_mode1=menuset::menu_no_sub("格式1",Message::WJ(menuset::WJMessage::Open) );
        // let wj_new_mode2=menuset::menu_no_sub("格式2",Message::WJ(menuset::WJMessage::Open) );
        let wj_new=menuset::menu_no_sub("新建", Message::WJ(menuset::WJMessage::New));
        let wj_save=menuset::menu_no_sub("保存",Message::WJ(menuset::WJMessage::Save));
        let wj_close=menuset::menu_no_sub("关闭",Message::WJ(menuset::WJMessage::Close));
        let wj_main=menuset::menu_main("文件", Message::WJ(menuset::WJMessage::WenJian), 
            vec![wj_open,wj_new,wj_save,wj_close]);
        let gj_title1_1=menuset::menu_no_sub("CatppuccinFrapp",Message::GFTheme(iced::Theme::CatppuccinFrappe));
        let gj_title1_2=menuset::menu_no_sub("CatppuccinLatte",Message::GFTheme(iced::Theme::CatppuccinLatte));
        let gj_title1_3=menuset::menu_no_sub("CatppuccinMacchiato",Message::GFTheme(iced::Theme::CatppuccinMacchiato));
        let gj_title1_4=menuset::menu_no_sub("CatppuccinMocha",Message::GFTheme(iced::Theme::CatppuccinMocha));
        let gj_title1_5=menuset::menu_no_sub("Dark",Message::GFTheme(iced::Theme::Dark));
        let gj_title1_6=menuset::menu_no_sub("Light",Message::GFTheme(iced::Theme::Light));
        let gj_title1_7=menuset::menu_no_sub("Dracula",Message::GFTheme(iced::Theme::Dracula));
        let gj_title1_8=menuset::menu_no_sub("Nord",Message::GFTheme(iced::Theme::Nord));
        let gj_title1_9=menuset::menu_no_sub("GruvboxDark",Message::GFTheme(iced::Theme::GruvboxDark));
        let gj_title1_10=menuset::menu_no_sub("GruvboxLight",Message::GFTheme(iced::Theme::GruvboxLight));

        let gj_title1=menuset::menu_with_sub("官方主题",Message::MenuNone,arrowsvg,vec![
            gj_title1_1,gj_title1_2,gj_title1_3,gj_title1_4,gj_title1_5,gj_title1_6,gj_title1_7,gj_title1_8,gj_title1_9,gj_title1_10,
        ]);
        let gj_title2_1=menuset::menu_no_sub("主题1",Message::GJ(menuset::GJMessage::T1));
        let gj_title2_2=menuset::menu_no_sub("主题2",Message::GJ(menuset::GJMessage::T2));
        let gj_title2_3=menuset::menu_no_sub("主题3",Message::GJ(menuset::GJMessage::T3));
        let gj_title2=menuset::menu_with_sub("自定义主题",Message::MenuNone,arrowsvg,vec![
            gj_title2_1,gj_title2_2,gj_title2_3,
        ]);
        let gj_title3_1=menuset::menu_no_sub_slider("R", Message::SliderChanged, self.slider_value,themecolor);
        let gj_title3_2=menuset::menu_no_sub_slider("G", Message::SliderChanged2, self.slider_value2,themecolor);
        let gj_title3_3=menuset::menu_no_sub_slider("B", Message::SliderChanged3,self.slider_value3,themecolor);
        let gj_title3_4=menuset::menu_no_sub_slider("A", Message::SliderChanged4,self.slider_value4,themecolor);
        let gj_title3=menuset::menu_with_sub("动态调整",Message::MenuNone,arrowsvg,vec![
            gj_title3_1,gj_title3_2,gj_title3_3,gj_title3_4,
        ]);
        let gj_main=menuset::menu_main("主题", Message::GJ(menuset::GJMessage::GongJv),
                vec![gj_title1,gj_title2,gj_title3]);
        let gy_gy=menuset::menu_no_sub("关于", Message::GY(menuset::GYMessage::GY));
        let gy_bz=menuset::menu_no_sub("帮助", Message::GY(menuset::GYMessage::BZ));
        let gy_gx=menuset::menu_no_sub("更新", Message::GY(menuset::GYMessage::GX));
        let gy_main=menuset::menu_main("帮助", Message::GY(menuset::GYMessage::GuanYu),
                vec![gy_gy,gy_bz,gy_gx]);
        
        let barstyle=iced_aw::style::menu_bar::MenuBarStyle::Custom(Box::new(menuset::MyMenuBarStyle{
                 //backcolor:Color::from_rgba8(106, 195, 251, 0.8),
                 backcolor:themecolor,
        }));
        let menu_bar=menuset::create_menubar(vec![
                                            wj_main,gj_main,gy_main,
                                        ],barstyle
                                        );
        let cont1=container(menu_bar
         ).padding(5);
        
        cont1.into()

    }
}


动态演示

rustGUI动态调整演示

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

YB4084系列 SOT23-5 耐压30V 600mA线性锂电池充电芯片,带热调节

电池充电-线性锂电池-YB4084系列 YB4084是一个完整的恒流恒压线性充电器为单节锂充电电池。由于内部P-MOSFET架构&#xff0c;不需要外部检测电阻&#xff0c;也不需要阻塞二极管。此外&#xff0c;YB4084是专门设计的USB电源规格内工作。它的SOT23-5封装和低外部元件计数使YB…

在Oracle VM virtual box 中复制 CentOS 7虚拟机更改IP地址的操作

最近玩Redis主从复制的时候&#xff0c;我装了一个虚拟机&#xff0c;但主从复制需要准备3个虚拟机&#xff0c;这个时候&#xff0c;我又不想一个一个去装&#xff0c;我看到Oracle VM virtual box提供了一个虚拟机复制操作&#xff0c;于是就用了一下这个功能&#xff0c;发现…

dotenv 配置踩坑-显示undefined

今天在学习dotenv,结果自己按照官方文档巧下来竟然还是不行&#xff0c;人麻了~ 这是我的目录结构 按照配置那么&#xff0c;我们只需要在config.default.js中写入如下代码就可以实现它将环境变量从文件加载到process.env中。 但是&#xff0c;但是这里犯了一个低级错误&#…

docker和docker-compose的安装

docker的安装 1.安装 curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun2.设置开机自启动 systemctl start docker #启动docker systemctl enable docker3.配置阿里云镜像 不配置镜像的话&#xff0c;进行 docker pull 等操作会比较慢。进入阿里云&…

基于django | 创建app,并启动django

1、删除系统默认的目录路径&#xff1a;BASE_DIR / templetes 2、在终端输入命令&#xff1a; python manage.py startapp app01 # 这里的app01是我创建app的名称 3、如果没有创建成功&#xff0c;手动点击 Creat App , 4、在 setting.py 中找到 INSTALLED_APPS ,添加 ap…

xml 取值错误 #{} boolean 一直为 false

取值时 #{param.msgStatus} 一直是false&#xff0c;java代码里面显示true。 <select id"findPageOaReading" resultType"com.focusin.data.office.func.dto.ProcessMessageInfoDTO">select i.*, t.template_name procdefNamefrom process_message_…

【办公类-04-02】华为助手导出照片读取拍摄时间分类导出,视频不行)

背景需求 今天我用QQ相册导出照片&#xff0c;但是始终在转圈&#xff0c;手机上无法跳出“连结“”的提示&#xff0c;换了台式和笔记本都无法传输。&#xff08;明明5月14日还可以导出的&#xff09; 最后我只能用华为传输助手&#xff0c;把照片快速提取出来了。 使用原来…

记录Nuxt 3 官网项目的一次部署

本来以为就是一次简单的部署&#xff0c;之前也是部署过几次nuxt项目了&#xff0c;所以&#xff0c;并没有要记录的想法。但是过程出现了很多问题&#xff0c;最后考虑还是写下来吧。留个记录&#xff08;完整的配置部署过程&#xff09; 这里我将要说明两种部署方式以供选择&…

ingress规则

一 k8s 对外服务之 Ingress LB ingress 1 Ingress 简介 service的作用体现在两个方面 ? ① 对集群内部&#xff0c;它不断跟踪pod的变化&#xff0c;更新endpoint中对应pod的对象&#xff0c;提供了ip不断变化的pod的服务发现机制&#xff1b; ② 对集群外部&#xff0c…

针对硅基氮化镓高电子迁移率晶体管(GaN-HEMT)的准物理等效电路模型,包含基板中射频漏电流的温度依赖性

来源&#xff1a;Quasi-Physical Equivalent Circuit Model of RF Leakage Current in Substrate Including Temperature Dependence for GaN-HEMT on Si&#xff08;TMTT 23年&#xff09; 摘要 该文章提出了一种针对硅基氮化镓高电子迁移率晶体管&#xff08;GaN-HEMT&…

逐步掌握最佳Ai Agents框架-AutoGen 九 RAG应用

在最近的几篇文章里&#xff0c;我们使用AutoGen实现了一些Demo。这篇文章&#xff0c;我们将使用AutoGen来完成RAG应用开发。 RAG应用 RAG全称"Retrieval-Augmented Generation",即检索增强生成&#xff0c;它是自然语言处理中的一项技术。这种模型结合了检索式&a…

【操作系统】(详细理解进程的状态)执行状态、就绪状态、阻塞状态、挂起状态

下面是进程的几种状态的概念&#xff1a; 执行状态&#xff1a;当一个进程已获得必要资源&#xff0c;并占有CPU进行执行。 就绪状体&#xff1a;进程已分配到除CPU外的所有必要资源&#xff0c;只要获取CPU允许就可立即执行。 阻塞状态&#xff1a;正在执行的进程&#xff0c;…

【NLP开发】Python实现聊天机器人(微信机器人)

&#x1f37a;NLP开发系列相关文章编写如下&#x1f37a;&#xff1a;1&#x1f388;【小沐学NLP】Python实现词云图&#x1f388;2&#x1f388;【小沐学NLP】Python实现图片文字识别&#x1f388;3&#x1f388;【小沐学NLP】Python实现中文、英文分词&#x1f388;4&#x1…

元宇宙3D品牌营销虚拟场景提升客户对企业的黏性

在这个充满创意与想象的3D元宇宙时代&#xff0c;我们为您推出了全新的3D元宇宙场景在线制作编辑平台&#xff0c;让您轻松构建专属的虚拟展厅&#xff0c;展现无限可能。 3D元宇宙场景在线制作编辑平台允许您快速完成空间设计&#xff0c;根据您的个性化需求&#xff0c;自由设…

云计算如何赋能工业数字化转型?

云计算在工业数字化转型中发挥着至关重要的作用&#xff0c;通过提供安全的数据存储与备份、强大的数据处理和分析能力、以及降低IT成本&#xff0c;为企业的数字化转型提供了坚实的技术支撑&#xff0c;助力企业实现数字化转型目标。 一、什么是云计算技术&#xff1f;有哪些基…

连锁品牌企业的税务策略,创业者的盈利秘籍!

随着全球经济的不断发展&#xff0c;连锁品牌企业已成为商业竞争中的重要力量。然而&#xff0c;在追求利润最大化的道路上&#xff0c;税务策略成为了企业不容忽视的一环。商淘云和你一起探讨连锁品牌企业的税务策略及创业者的盈利秘籍&#xff0c;着重介绍税务合规管理、税务…

适合初学者人手一本的LLM大语言模型综述,爆火全网

今天给大家推荐一本大模型&#xff08;LLM&#xff09;这块的一本外文书&#xff0c;经过整理已经出中文版了&#xff0c;就是这本《大型语言模型综述》&#xff01;本书在git上有9.2k star&#xff0c;还是很不错的一本大模型方面的书。 本教程内容主要内容&#xff1a;中文版…

防火墙是什么?探讨部署Web防火墙的必要性

如今&#xff0c;多云环境、API安全功能扩展、合作伙伴集成即时可用、可用性和可视化增强以及提高自动化程度已经成为基本要求。伴随企业应用架构的迁移&#xff0c;在用户端&#xff0c;需要在部署环境不断扩展但人员技能有限的情况下&#xff0c;保护数量日益增长的应用安全。…

libsystemctlm-soc项目分析

概述 libsystemctlm-soc项目是Xilinx的SystemC库。 环境安装 verilator安装 # Prerequisites: #sudo apt-get install git help2man perl python3 make autoconf g flex bison ccache #sudo apt-get install libgoogle-perftools-dev numactl perl-doc #sudo apt-get insta…

vulhub中PHP利用GNU C Iconv将文件读取变成RCE(CVE-2024-2961)

GNU C 是一个标准的ISO C依赖库。在GNU C中&#xff0c;iconv()函数2.39及以前存在一处缓冲区溢出漏洞&#xff0c;这可能会导致应用程序崩溃或覆盖相邻变量。 如果一个PHP应用中存在任意文件读取漏洞&#xff0c;攻击者可以利用iconv()的这个CVE-2024-2961漏洞&#xff0c;将…