第6章 6章:文本
文本可能是图形用户界面中最基础的组件。
在 iced 中,展示文本的方式有很多种,但最常见的是使用 widget 模块下的 text 辅助函数来构建 Text 组件实例。
use iced::widget::Text;
fn main() -> iced::Result {
iced::run((), view)
}
fn view(_: &()) -> Text<'_> {
use iced::widget::text;
use iced::{Fill, Font};
text("- Hello there!\n- General Kenobi!")
.font(Font::MONOSPACE)
.size(30) // in logical pixels
.line_height(1.5) // relative to the size (=45px)
.width(Fill)
.height(Fill)
.center()
}
对齐
Text 组件会在自身边界内对齐其内容。
由于 Text 组件默认采用内在尺寸策略,其边界会与内容尺寸一致。这意味着,如果不改变默认的尺寸策略,调整文本对齐将不会产生任何效果。
use iced::widget::Text;
fn main() -> iced::Result {
iced::run((), view)
}
fn view(_: &()) -> Text<'_> {
use iced::widget::text;
text("This text will not be centered").center()
}
如果显式将 width 设为 Fill,就能实现预期的水平居中对齐:
use iced::widget::Text;
fn main() -> iced::Result {
iced::run((), view)
}
fn view(_: &()) -> Text<'_> {
use iced::widget::text;
use iced::Fill;
text("This text will be centered horizontally")
.width(Fill)
.center()
}
对 height 做同样的处理,即可在水平和垂直两个方向上同时对齐:
use iced::widget::Text;
fn main() -> iced::Result {
iced::run((), view)
}
fn view(_: &()) -> Text<'_> {
use iced::widget::text;
use iced::Fill;
text("This text will be centered")
.width(Fill)
.height(Fill)
.center()
}
当然,也可以在固定尺寸的内部进行对齐:
use iced::widget::Text;
fn main() -> iced::Result {
iced::run((), view)
}
fn view(_: &()) -> Text<'_> {
use iced::widget::text;
text("这段文字将居中显示在一个 150x150 的方形区域内")
.width(150)
.height(150)
.center()
}
样式定制
你可以通过 Text 组件的不同方法来改变其外观,例如调整所使用的 font 及其字号,或更改文本的 color。
而 style 方法能让你利用应用程序当前的 Theme 来指定文本颜色:
use iced::widget::Text;
fn main() -> iced::Result {
iced::run((), view)
}
fn view(_: &()) -> Text<'_> {
use iced::widget::text;
use iced::Theme;
text("这是当前主题的主色调!")
.style(|theme: &Theme| text::Style {
color: Some(theme.palette().primary),
})
}
为了方便起见,widget::text 模块内置了一些辅助函数,可直接传递给 style 使用:
use iced::widget::Text;
fn main() -> iced::Result {
iced::run((), view)
fn view(_: &()) -> Text<'_> {
use iced::widget::text;
text("And this is the warning color!")
.style(text::warning)
}
所有内置组件都遵循这一模式,请牢记!
text! 宏
你经常需要用 format! 把动态值和静态文本拼接起来,比如:
use iced::widget::Text;
fn main() -> iced::Result {
iced::run((), view)
fn view(_: &()) -> Text<'_> {
use iced::widget::text;
let name = "Héctor"; // 假设这是动态值
text(format!("Hello, {name}!"))
}
text! 宏正是为这种场景设计的。它的用法和 format! 完全一样,只是返回的是 Text 组件而不是 String。
use iced::widget::Text;
fn main() -> iced::Result {
iced::run((), view)
fn view(_: &()) -> Text<'_> {
use iced::widget::text;
let name = "Héctor"; // 假设这是动态值
text!("Hello, {name}!")
}
引入 iced::widget::text 后,你无需单独引入宏。Rust 会在这一条 import 中同时提供 text 辅助函数、text 模块以及 text! 宏。
相当巧妙!
字符串切片
Text 控件为 Element 实现了 From<&str>。
由于大多数构建控件的辅助函数都接受 Into<Element>,有了这一实现,只要手里有字符串切片,你就可以完全跳过 text() 调用。
use iced::widget::Container;
use iced::Never;
fn main() -> iced::Result {
iced::run((), view)
}
fn view(_: &()) -> Container<'_, Never> {
use iced::widget::container;
// 你可以直接返回:
// container(text("冗余"))
//
// 但下面写法等效:
container("简洁明了!")
}
只有当你希望使用默认文本外观时,才能这样做。如需定制外观,则必须使用 text 辅助函数。