概述
iced 是一个受 Elm 架构启发的跨平台 GUI 库,专注于简洁性与类型安全。
快速入门
1. 启动应用
调用 run 函数作为程序入口:
pub fn main() -> iced::Result {
iced::run(update, view)
}
2. 定义消息
创建枚举连接界面与逻辑:
#[derive(Debug, Clone)]
enum Message {
Increment,
}
3. 更新状态
实现 update 函数处理消息:
fn update(counter: &mut u64, message: Message) {
match message {
Message::Increment => *counter += 1,
}
}
4. 渲染视图
实现 view 函数展示界面:
use iced::widget::{button, text};
use iced::Element;
fn view(counter: &u64) -> Element<'_, Message> {
button(text(counter)).on_press(Message::Increment).into()
}
核心概念
自定义状态
使用结构体组织状态数据:
#[derive(Default)]
struct Counter {
value: u64,
}
fn update(counter: &mut Counter, message: Message) {
match message {
Message::Increment => counter.value += 1,
}
}
fn view(counter: &Counter) -> Element<'_, Message> {
button(text(counter.value)).on_press(Message::Increment).into()
}
Widget 与 Element
- Element 是泛型 widget 的封装
- 通过构建器模式配置 widget:
use iced::widget::{button, column, text};
fn view(counter: &Counter) -> Element<'_, Message> {
column![
text(counter.value).size(20),
button("Increment").on_press(Message::Increment),
]
.spacing(10)
.into()
}
- 使用 .into() 将具体 widget 转换为 Element
- Element 的消息类型必须与 update 函数一致
布局系统
每个 widget 实现独立的布局策略,常用组合方式:
use iced::widget::{column, container, row};
use iced::{Fill, Element};
fn view(state: &State) -> Element<'_, Message> {
container(
column![
"Top",
row!["Left", "Right"].spacing(10),
"Bottom"
]
.spacing(10)
)
.padding(10)
.center_x(Fill)
.center_y(Fill)
.into()
}
- Row/Column:水平/垂直排列子元素
- Container:定位或对齐单个 widget
尺寸设置
使用 Length 控制 widget 尺寸:
- Fill:填充所有可用空间
- Shrink:适应自身内容(默认)
- 固定像素值:
container("I am 300px tall!").height(300).into()
主题系统
通过 Application 构建器自定义主题:
use iced::Theme;
pub fn main() -> iced::Result {
iced::application(new, update, view)
.theme(theme)
.run()
}
fn theme(state: &State) -> Theme {
Theme::TokyoNight // 支持内置主题或自定义主题
}
样式定制
通过 style 方法设置 widget 外观:
use iced::widget::{button, container};
use iced::{Element, Theme};
// 使用内置样式
container("Rounded box").style(container::rounded_box).into()
// 自定义样式
button("Styled button").style(|theme: &Theme, status| {
match status {
button::Status::Active => button::Style::default()
.with_background(theme.extended_palette().success.strong.color),
_ => button::primary(theme, status),
}
}).into()
- 样式闭包接收主题和 widget 状态
- 可通过 palette() 或 extended_palette() 获取调色板
- 各模块提供便捷样式函数(如 button::primary)
高级特性
并发任务
update 可返回 Task 执行异步操作:
use iced::Task;
struct State { weather: Option<Weather> }
enum Message {
FetchWeather,
WeatherFetched(Weather),
}
fn update(state: &mut State, message: Message) -> Task<Message> {
match message {
Message::FetchWeather => Task::perform(
fetch_weather(),
Message::WeatherFetched,
),
Message::WeatherFetched(weather) => {
state.weather = Some(weather);
Task::none()
}
}
}
async fn fetch_weather() -> Weather { /* … */ }
任务支持:
- 映射、链式组合、批处理、取消等操作
- 与运行时交互(窗口设置、焦点控制等)
被动订阅
监听外部数据源:
use iced::{window, Size, Subscription};
pub fn main() -> iced::Result {
iced::application(new, update, view)
.subscription(subscription)
.run()
}
fn subscription(state: &State) -> Subscription<Message> {
window::resize_events()
.map(|(_id, size)| Message::WindowResized(size))
}
- 订阅是声明式的,活跃订阅完全由 subscription 函数决定
- 支持时间事件、键盘监听等,也可通过 Subscription::run 自定义
应用组合
将应用拆分为独立屏幕(页面):
struct State { screen: Screen }
enum Screen {
Contacts(Contacts),
Conversation(Conversation),
}
enum Message {
Contacts(contacts::Message),
Conversation(conversation::Message),
}
fn update(state: &mut State, message: Message) -> Task<Message> {
match (message, &mut state.screen) {
(Message::Contacts(msg), Screen::Contacts(contacts)) => {
match contacts.update(msg) {
contacts::Action::Chat(contact) => {
let (conversation, task) = Conversation::new(contact);
state.screen = Screen::Conversation(conversation);
task.map(Message::Conversation)
}
contacts::Action::Run(task) => task.map(Message::Contacts),
contacts::Action::None => Task::none(),
}
}
(Message::Conversation(msg), Screen::Conversation(conversation)) => {
conversation.update(msg).map(Message::Conversation)
}
_ => Task::none(),
}
}
fn view(state: &State) -> Element<'_, Message> {
match &state.screen {
Screen::Contacts(contacts) => contacts.view().map(Message::Contacts),
Screen::Conversation(conversation) => conversation.view().map(Message::Conversation),
}
}
通过 Action 枚举实现屏幕间类型安全的转换和通信。
API 参考
重导出
pub use application::Application;
pub use daemon::Daemon;
pub use iced_futures::futures;
pub use iced_highlighter as highlighter;
pub use iced_renderer::wgpu::wgpu;
pub use Alignment::Center;
pub use Length::{Fill, FillPortion, Shrink};
pub use alignment::Horizontal::{Left, Right};
pub use alignment::Vertical::{Bottom, Top};
主要模块
| advanced | 自定义 widget 等高级功能 |
| widget | 内置 widget 及自定义接口 |
| application | 应用程序创建与运行 |
| window | 窗口配置与管理 |
| theme | 内置主题与样式 |
| task | 运行时任务创建 |
| subscription | 外部事件监听 |
常用类型
- Element:通用 widget 类型
- Task:并发操作集合
- Subscription:外部事件监听请求
- Length:尺寸策略(Fill/Shrink/固定值)
- Theme:内置主题(TokyoNight 等)
核心函数
- run:基础应用启动
- application:带主题和订阅的应用构建
- exit:退出运行时任务
- never:不可调用函数(用于类型占位)
设计理念
iced 通过以下原则实现简洁性与类型安全:
- Elm 架构:单向数据流,可预测的状态管理
- 类型驱动:编译期保证消息处理完整性
- 声明式 UI:视图完全由状态决定
- 组合优先:通过函子接口无缝组合组件
- 无统一样式系统:每个 widget 独立实现样式,保持灵活性



