Rust 基于 iced crate 实现一个简易时钟

分类:Rust     发布时间:2025-07-22     最后更新:2025-07-28     浏览数:109
详细介绍 Rust 基于 iced crate 实现一个时钟的完整示例。 知识点包括 iced 的 subscription,窗口图标,程序图标,自定义字体,打包优化。

本文将详细介绍基于 iced 实现一个时钟的完整示例。

知识点

  • iced 的 subscription
  • 窗口图标
  • 程序图标
  • 自定义字体
  • 打包优化
  • 在 release 版本中,防止在 Windows 上出现额外的控制台窗口

预览

UI

优化后的文件大小

开发环境

  • 系统:Windows 11 专业版
  • 编辑器:Visual Studio Code
  • cargo:1.85.1 (d73d2caf9 2024-12-31)
  • 编译工具链:stable-x86_64-pc-windows-msvc (active, default)

代码

Cargo.toml

[package]
name = "clock"
version = "0.0.1"
edition = "2024"
build = "build.rs"

[dependencies]
chrono = "0.4.41" # 时间格式化
iced = { version = "0.13.1", features = ["image", "tokio"] } # image 特性是为了导入窗口图标。tokio 是为了启用 iced::time 定时器

[build-dependencies]
winres = "0.1.12" # 为可执行文件添加元信息和图标

[profile.release]
strip = true
lto = true
opt-level = "z"

build.rs

extern crate winres;

fn main() {
  if cfg!(target_os = "windows") {
    let mut res = winres::WindowsResource::new();
    res.set_icon("res/icon.ico");
    res.compile().unwrap();
  }
}

main.rs

// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]

use std::time::Duration;

use chrono::Local;
use iced::{
    Element, Font, Length, Size, Subscription,
    widget::{column, container, text},
    window::{Icon, Settings, icon},
};

#[derive(Default)]
struct ClockApp {
    current_time: String,
}

#[derive(Debug, Clone, Copy)]
pub enum Message {
    Tick,
}

impl ClockApp {
    pub fn view(&self) -> Element<Message> {
        container(column![text(&self.current_time).size(26),])
            .center(Length::Fill)
            .into()
    }

    pub fn update(&mut self, message: Message) {
        match message {
            Message::Tick => {
                let now = Local::now();
                self.current_time =
                    format!("{} {}", now.format("%Y-%m-%d"), now.format("%H:%M:%S"));
            }
        }
    }

    fn subscription(&self) -> Subscription<Message> {
        iced::time::every(Duration::from_millis(1000)).map(|_| Message::Tick)
    }
}

fn main() -> iced::Result {
    iced::application("Clock", ClockApp::update, ClockApp::view)
        .font(include_bytes!("../res/MapleMono-Regular.ttf"))
        .default_font(Font::with_name("Maple Mono"))
        .window(Settings {
            icon: Some(Icon::from(
                icon::from_file_data(include_bytes!("../res/icon.ico"), None).unwrap(),
            )),
            size: Size::new(400.0, 200.0),
            ..Default::default()
        })
        .subscription(ClockApp::subscription)
        .run()
}

注: icon.ico 宽高是 256px * 256px

Maple Mono font

参考

https://zhuanlan.zhihu.com/p/16785239921

https://crates.io/crates/winres

https://crates.io/crates/chrono

https://docs.rs/iced/latest/iced/index.html#passive-subscriptions

https://font.subf.dev/zh-cn/download/

上一篇: 米家应用添加小米电视 下一篇: 没有了