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 界面编程一个小例子
分享到: 新浪微博 微信 QQ好友 QQ空间 豆瓣
rust编译减小安装包的参数配置和方法 »

相关文章

发表回复

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




Enter Captcha Here :

qq
微信
微信
返回顶部

玻璃钢生产厂家新余商场美陈厂家直销汕头商业美陈临沧不锈钢雕塑价格盘锦玻璃钢沙发价格宿迁玻璃钢树池坐凳价格湛江玻璃钢休闲椅生产厂家商洛玻璃钢花池加工泸州商场美陈哪家好常州玻璃钢景观雕塑定制无锡玻璃钢医疗外壳公司温州玻璃钢卡通雕塑制作北海玻璃钢前台批发鹤岗玻璃钢机械外壳加工衡阳商场美陈定制江苏玻璃钢垃圾桶价格丽江玻璃钢树池厂来宾玻璃钢花槽价格铜仁玻璃钢座椅厂承德玻璃钢装饰造型哪家好唐山玻璃钢雕塑云浮玻璃钢摆件三沙玻璃钢餐桌椅多少钱雅安玻璃钢动物雕塑生产厂家承德玻璃钢花箱厂家盐城玻璃钢设备外壳制作滨州玻璃钢餐桌椅定做宿州玻璃钢花坛制造拉萨玻璃钢雕塑多少钱安徽玻璃钢种植池安阳玻璃钢浮雕定制香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声卫健委通报少年有偿捐血浆16次猝死汪小菲曝离婚始末何赛飞追着代拍打雅江山火三名扑火人员牺牲系谣言男子被猫抓伤后确诊“猫抓病”周杰伦一审败诉网易中国拥有亿元资产的家庭达13.3万户315晚会后胖东来又人满为患了高校汽车撞人致3死16伤 司机系学生张家界的山上“长”满了韩国人?张立群任西安交通大学校长手机成瘾是影响睡眠质量重要因素网友洛杉矶偶遇贾玲“重生之我在北大当嫡校长”单亲妈妈陷入热恋 14岁儿子报警倪萍分享减重40斤方法杨倩无缘巴黎奥运考生莫言也上北大硕士复试名单了许家印被限制高消费奥巴马现身唐宁街 黑色着装引猜测专访95后高颜值猪保姆男孩8年未见母亲被告知被遗忘七年后宇文玥被薅头发捞上岸郑州一火锅店爆改成麻辣烫店西双版纳热带植物园回应蜉蝣大爆发沉迷短剧的人就像掉进了杀猪盘当地回应沈阳致3死车祸车主疑毒驾开除党籍5年后 原水城县长再被查凯特王妃现身!外出购物视频曝光初中生遭15人围殴自卫刺伤3人判无罪事业单位女子向同事水杯投不明物质男子被流浪猫绊倒 投喂者赔24万外国人感慨凌晨的中国很安全路边卖淀粉肠阿姨主动出示声明书胖东来员工每周单休无小长假王树国卸任西安交大校长 师生送别小米汽车超级工厂正式揭幕黑马情侣提车了妈妈回应孩子在校撞护栏坠楼校方回应护栏损坏小学生课间坠楼房客欠租失踪 房东直发愁专家建议不必谈骨泥色变老人退休金被冒领16年 金额超20万西藏招商引资投资者子女可当地高考特朗普无法缴纳4.54亿美元罚金浙江一高校内汽车冲撞行人 多人受伤

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化