rust fltk-rs 界面编程一个小例子

rust 性能出色,但其gui库并不是很多,成熟的就更少了,而fltk-rs作为fltk rust语言的绑定,基本是够用的。本文描述了一个fltk-rs 编程的一个小例子,代码如下:

main.rs

#![windows_subsystem = "windows"]
#[allow(dead_code)]
#[warn(unreachable_patterns)]
use fltk::{
    App,
    enums::{FrameType, *},
    frame::Frame,
    image::{SharedImage, SvgImage},
    prelude::*,
    window::Window,
    *,
};
use fltk::{
    button::Button,
    group::Flex,
    text::{TextBuffer, TextEditor},
};
use reqwest::Error;
// use opener;
use std::time::Duration;
use std::{process::Command, thread};
fn main() {
    let app = app::App::default().with_scheme(app::Scheme::Gtk);
    app::background(230, 230, 230);
    let (width, _height) = app::screen_size();
    let mut wind = Window::new(100, 100, 800, 600, "fltk test 04").center_screen();
    //窗口关闭事件
    wind.set_callback(|_| {
        let (width, height) = app::screen_size();
        if app::event() == enums::Event::Close {
            let dialog = dialog::choice2(
                ((width / 2.0) as i32) - 200,
                ((height / 2.0) as i32) - 100,
                "确定退出吗?",
                "否",
                "是",
                "取消",
            )
            .unwrap();
            println!("dialog: {}", dialog);
            if dialog == 1 {
                app::quit();
                std::process::exit(0);
            }
        }
    });
    //图标
    wind.set_icon(Some(SvgImage::load("screenshots/logo.svg").unwrap()));
    let mut menu = menu::MenuBar::default().with_size(800, 35);
    menu.set_frame(FrameType::FlatBox);
    menu.add(
        "文件/新建\t",
        Shortcut::Ctrl | 'n',
        menu::MenuFlag::Normal,
        menu_cb,
    );
    menu.add(
        "文件/保存\t",
        Shortcut::Ctrl | 'w',
        menu::MenuFlag::Normal,
        menu_cb,
    );
    menu.add(
        "文件/退出\t",
        Shortcut::Ctrl | 'x',
        menu::MenuFlag::Normal,
        menu_cb,
    );
    menu.add(
        "编辑/改写\t",
        Shortcut::None,
        menu::MenuFlag::Normal,
        menu_cb,
    );
    menu.add(
        "编辑/字句\t",
        Shortcut::None,
        menu::MenuFlag::Normal,
        menu_cb,
    );
    menu.add(
        "编辑/规则\t",
        Shortcut::None,
        menu::MenuFlag::Normal,
        menu_cb,
    );
    let mut frame = Frame::new(10, 50, 780, 60, "");
    frame.set_frame(FrameType::EngravedBox);
    let mut btn1 = Button::new(20, 70, 60, 30, "@< 开始");
    let mut btn2 = Button::new(90, 70, 60, 30, "@>| 结束");
    btn2.set_frame(FrameType::GleamUpBox);
    let flex = Flex::new(220, 70, 120, 30, "").column();
    let mut choice_thread = menu::Choice::default().with_label("多线程");
    for i in 1..10 {
        choice_thread.add_choice(&i.to_string());
    }
    //设置默认值
    choice_thread.set_value(6);
    //获取默认值
    println!("{}", choice_thread.value() + 1);
    //监听
    choice_thread.set_callback(|c| {
        let v = c.value();
        match v {
            v => println!("{} is selected!", v + 1),
        }
    });
    flex.end();
    let mut btn_img = Button::new(350, 60, 340, 40, None);
    btn_img.set_frame(FrameType::NoBox);
    // 设置程序图标
    let mut image = SharedImage::load("screenshots/logo.png").unwrap();
    image.scale(240, 50, true, true);
    btn_img.set_image(Some(image));
    //  button tooltip message
    btn_img.set_tooltip("点击访问官方网页");
    //打开网址
    btn_img.set_callback(|_| {
        let url = "https://www.lanhong-vip.com";
        Command::new("cmd.exe")
            .args(["/C", "start", url])
            .output()
            .expect("调用失败");
    });
    // let mut btn3 = Button::new(710,70,60,30,"@<- 退出");
    let mut frame2 = Frame::new(10, 120, 780, 320, "");
    frame2.set_frame(FrameType::EngravedBox);
    let flex2 = Flex::new(20, 140, 760, 280, "").column();
    let mut text1 = TextEditor::default().center_of(&flex2);
    let buffer = TextBuffer::default();
    let buffer2: TextBuffer = buffer.clone();
    text1.set_buffer(buffer.clone());
    flex2.end();
    let width = (width / 1.0) as i32;
    let mut frame3 = Frame::new(50, 450, 700, 60, "");
    frame3.set_frame(FrameType::EngravedBox);
    let input_url = input::Input::new(100, 465, 400, 30, "网址:");
    let mut choice_encode = menu::Choice::new(520, 465, 100, 30, "");
    choice_encode.add_choice("选择编码");
    choice_encode.add_choice("utf-8");
    choice_encode.add_choice("gbk");
    choice_encode.set_value(0);
    let mut btn_submit = button::Button::new(630, 465, 60, 30, "@> 提交");
    btn_submit.set_callback(move |btn_submit| {
        let mut btn_sumbit_clone = btn_submit.clone();
        let mut value = input_url.value().trim().to_string();
        if value.len() == 0 {
            value = "是空的".to_string();
            dialog::message_title_default("提示");
            dialog::alert(
                width / 2 - 200,
                width / 4 - 100,
                &format!("你输入的是:\t{}", value),
            );
        } else {
            let mut buffer2 = buffer2.clone();
            btn_sumbit_clone.deactivate();
            let charset_index = choice_encode.value();
            let mut charset = "utf-8";
            if charset_index == 0 || charset_index == 1 {
                charset = "utf-8";
            } else if charset_index == 2 {
                charset = "gbk";
            }
            thread::spawn(move || {
                let res = get_content_by_url(&value, &charset);
                match res {
                    Ok(r) => buffer2.set_text(&r),
                    Err(e) => buffer2.set_text(&e.to_string()),
                }
                btn_sumbit_clone.activate();
            });
        }
    });
    let flex3 = Flex::default().column().center_of_parent();
    flex3.end();
    let mut frame4 = Frame::new(0, 580, width, 320, "");
    frame4.set_frame(FrameType::EngravedBox);
    let mut label1 = Button::new(0, 580, 40, 20, "状态栏");
    label1.set_frame(FrameType::NoBox);
    let mut status_bar_text = Button::new(150, 580, 450, 20, None);
    status_bar_text.set_frame(FrameType::NoBox);
    status_bar_text.set_align(Align::Left);
    status_bar_text.set_label_color(Color::Blue);
    //必须克隆一个btn2,否则会涉及到多次借用,编译不通过
    let mut bt2 = btn2.clone();
    let mut bt1 = btn1.clone();
    btn1.set_callback(move |btn1| match btn1.value() {
        false => {
            let mut b = buffer.clone();
            let mut status = status_bar_text.clone();
            let mut text_area = text1.clone();
            let c = btn1.clone();
            let mut btn1_1 = btn1.clone();
            let mut btn2_2 = bt2.clone();
            bt2.activate();
            btn1.deactivate();
            //多线程
            thread::spawn(move || {
                for i in 1..10000 {
                    //停止标志
                    if c.active() {
                        break;
                    }
                    let st = "第".to_owned() + &(i.to_string()) + "个";
                    status.set_label(&st);
                    b.append(&(i.to_string() + "-添加生成的内容\n"));
                    thread::sleep(Duration::from_nanos(0));
                }
                //一直往下滚动
                let line = b.text().split("\n").count().try_into().unwrap();
                text_area.scroll(line, 1);
                btn1_1.activate();
                btn2_2.deactivate();
            });
        }
        true => {
            bt2.deactivate();
            bt1.activate();
        }
    });
    btn2.set_callback(move |btn2| match btn2.value() {
        false => {
            btn1.activate();
            btn2.deactivate();
        }
        true => {
            btn1.deactivate();
            btn2.activate();
        }
    });
    let flex4 = Flex::new(0, 580, width, 40, "").column();
    flex4.end();
    wind.make_resizable(true);
    wind.end();
    wind.show();
    app.run().unwrap();
}
/**
 * 菜单事件监听
 */
fn menu_cb(m: &mut impl MenuExt) {
    dialog::message_title_default("退出程序?");
    if let Some(choice) = m.choice() {
        //匹配每个菜单项
        let (width, height) = app::screen_size();
        match choice.as_str() {
            "新建\t" => println!("New"),
            "退出\t" => {
                //居中显示x,y参数是关键
                let dialog = dialog::choice2(
                    (width / 2.0) as i32 - 200,
                    (height / 2.0) as i32 - 100,
                    "确定退出吗?",
                    "否",
                    "是",
                    "取消",
                )
                .unwrap();
                if dialog == 1 {
                    app::quit();
                }
            }
            _ => println!("{}", choice),
        }
    }
}
fn get_content_by_url(url: &str, charset: &str) -> Result<String, Error> {
    let r = reqwest::blocking::get(url);
    //异常处理
    match r {
        Ok(re) => {
            let res = re.text_with_charset(charset).unwrap();
            let document = scraper::Html::parse_document(&res);
            let title_select = document.root_element();
            Ok(title_select.html())
        }
        Err(e) => Err(e),
    }
}

 

cargo.toml 内容
[package]
name = "test_04"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
fltk = "*"
reqwest = {version ="0.11",features = ["blocking",'json']}
scraper = "*"

 

最终界面如下:
rust fltk-rs 界面编程一个小例子
rust编译减小安装包的参数配置和方法 »

相关文章

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注




Enter Captcha Here :

qq
微信
微信
分享本页
返回顶部

深圳SEO优化公司江苏常州网站优化新乡百度网站优化费用多少惠城网站优化公司潮州专业网站优化公司上饶郴州企业网站优化方案做神马网站优化厂家营销型网站建设优化菏泽外贸网站优化网站排名优化方法快速排名窍门自贡衢州网站优化沧州网站搜索优化排名报价网站标题的优化软件太原网站排名优化桂城网站优化作用云南营销网站seo优化优化网站标题的名词解释网站网络营销的优化服务沈阳网站怎么优化排名靠前江北新区快速网站优化潮州网站首页关键词优化教程井陉网站优化seo费用郑州瓷砖行业网站优化推广可靠吗嘉兴优化网站公司哪家好怎么做网站优化 sit跳出高的网站如何优化汕尾资深的免费网站优化泰州什么叫网站优化兰州网站优化哪家快西宁网站优化哪里有孝南区网站优化作用歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化