Rust GUI框架Relm4宏库relm4-macros的使用:简化GTK4应用开发的声明式宏工具
Relm4-macros
一个用于轻松为Relm4应用程序生成UI的宏库。
安装
在项目目录中运行以下Cargo命令:
cargo add relm4-macros
或者在Cargo.toml中添加以下行:
relm4-macros = "0.9.1"
示例代码
下面是一个使用relm4-macros创建简单GTK4应用的完整示例:
use relm4::*;
use gtk::prelude::*;
// 定义应用结构体
pub struct App {
counter: u8,
}
// 定义消息类型
#[derive(Debug)]
pub enum AppMsg {
Increment,
Decrement,
}
// 使用relm4_macros宏定义组件
#[relm4_macros::component]
impl SimpleComponent for App {
// 初始化模型
fn init(
_counter: u8,
_root: &Self::Root,
_sender: Sender<AppMsg>,
) -> ComponentParts<Self> {
let model = App { counter: 0 };
// 创建UI widgets
let widgets = view! {
gtk::ApplicationWindow {
set_title: Some("Simple app"),
set_default_size: (300, 100),
gtk::Box {
set_orientation: gtk::Orientation::Vertical,
set_spacing: 5,
set_margin_all: 5,
append: >k::Button {
set_label: "Increment",
connect_clicked => AppMsg::Increment,
},
append: >k::Button {
set_label: "Decrement",
connect_clicked => AppMsg::Decrement,
},
append: >k::Label {
set_margin_all: 5,
#[watch]
set_label: &format!("Counter: {}", model.counter),
},
},
}
};
ComponentParts { model, widgets }
}
// 更新模型逻辑
fn update(&mut self, msg: AppMsg, _sender: Sender<AppMsg>) {
match msg {
AppMsg::Increment => {
self.counter = self.counter.wrapping_add(1);
}
AppMsg::Decrement => {
self.counter = self.counter.wrapping_sub(1);
}
}
}
}
// 运行应用
fn main() {
let app = RelmApp::new("relm4.example.simple");
app.run::<App>(0);
}
完整示例demo
以下是一个更完整的计数器应用示例,添加了更多功能和UI元素:
use relm4::*;
use gtk::prelude::*;
use gtk::{glib, ApplicationWindow};
// 定义应用模型
pub struct AppModel {
counter: i32,
max_value: i32,
min_value: i32,
}
// 定义消息类型
#[derive(Debug)]
pub enum AppMsg {
Increment,
Decrement,
Reset,
SetMax(i32),
SetMin(i32),
}
// 定义组件部件
#[relm4_macros::component]
impl SimpleComponent for AppModel {
// 初始化模型
fn init(
_params: (),
_root: &Self::Root,
sender: Sender<AppMsg>,
) -> ComponentParts<Self> {
let model = AppModel {
counter: 0,
max_value: 10,
min_value: -10,
};
// 创建UI widgets
let widgets = view! {
gtk::ApplicationWindow {
set_title: Some("Advanced Counter"),
set_default_size: (400, 200),
gtk::Box {
set_orientation: gtk::Orientation::Vertical,
set_spacing: 10,
set_margin_all: 10,
// 计数器显示
append: >k::Label {
set_margin_all: 10,
#[watch]
set_label: &format!("当前值: {}", model.counter),
set_css_classes: &["title-1"],
},
// 按钮区域
append: >k::Box {
set_orientation: gtk::Orientation::Horizontal,
set_spacing: 5,
set_halign: gtk::Align::Center,
append: >k::Button {
set_label: "-",
connect_clicked => AppMsg::Decrement,
set_tooltip_text: Some("减少计数器"),
},
append: >k::Button {
set_label: "重置",
connect_clicked => AppMsg::Reset,
},
append: >k::Button {
set_label: "+",
connect_clicked => AppMsg::Increment,
set_tooltip_text: Some("增加计数器"),
},
},
// 设置区域
append: >k::Frame {
set_label: Some("设置"),
set_margin_top: 10,
gtk::Box {
set_orientation: gtk::Orientation::Vertical,
set_spacing: 5,
set_margin_all: 5,
append: >k::SpinButton {
set_range: (i32::MIN as f64, i32::MAX as f64),
set_value: model.max_value as f64,
set_increments: (1.0, 10.0),
set_digits: 0,
connect_value_changed => move |spin| {
sender.send(AppMsg::SetMax(spin.value_as_int())).unwrap();
},
},
append: >k::Label {
set_label: "最大值限制",
},
append: >k::SpinButton {
set_range: (i32::MIN as f64, i32::MAX as f64),
set_value: model.min_value as f64,
set_increments: (1.0, 10.0),
set_digits: 0,
connect_value_changed => move |spin| {
sender.send(AppMsg::SetMin(spin.value_as_int())).unwrap();
},
},
append: >k::Label {
set_label: "最小值限制",
},
},
},
},
}
};
ComponentParts { model, widgets }
}
// 更新模型逻辑
fn update(&mut self, msg: AppMsg, _sender: Sender<AppMsg>) {
match msg {
AppMsg::Increment => {
if self.counter < self.max_value {
self.counter += 1;
}
}
AppMsg::Decrement => {
if self.counter > self.min_value {
self.counter -= 1;
}
}
AppMsg::Reset => {
self.counter = 0;
}
AppMsg::SetMax(value) => {
self.max_value = value;
if self.counter > value {
self.counter = value;
}
}
AppMsg::SetMin(value) => {
self.min_value = value;
if self.counter < value {
self.counter = value;
}
}
}
}
}
// 运行应用
fn main() {
let app = RelmApp::new("relm4.example.advanced");
app.run::<AppModel>(());
}
特性
- 声明式UI语法,类似React的JSX
- 自动处理GTK widget的创建和配置
- 响应式数据绑定
- 简洁的消息处理机制
- 编译时类型检查
许可证
Apache-2.0 OR MIT
1 回复