如何让Slint的Text组件自动布局宽度并在Rust中读取该宽度?
Slint无限文本滚动:获取自动布局文本宽度的解决方案
核心问题原因
直接给Text组件绑定width到外部属性会强制固定宽度,破坏Slint的自动布局逻辑,导致无法获取文本的自然宽度(即容纳内容所需的实际宽度)。
解决方案
不要手动设置Text的width,而是利用Slint内置的natural-width属性获取文本的自然宽度,再将该值导出给Rust代码,同时通过容器裁剪实现可视区域控制。
修改后的Slint代码
in-out property <length> offset_x: 0px; // 导出文本的自然宽度给Rust out property <length> text_natural_width: 0px; // 可视容器:固定宽度并开启裁剪 Rectangle { width: 300px; // 根据需求设置滚动区域的可视宽度 clip: true; // 横向布局放置两个重复文本,实现无缝滚动 HorizontalLayout { x: offset_x; spacing: 0; Text { text: "需要滚动的文本内容"; // 将文本的自然宽度绑定到外部属性 text_natural_width: self.natural-width; } Text { text: "需要滚动的文本内容"; // 重复文本,滚动时实现无缝衔接 } } }
Rust侧滚动逻辑实现
读取导出的text_natural_width值,通过定时器逐步调整offset_x,当偏移量超过单个文本宽度时重置,实现无限滚动:
use slint::ComponentHandle; fn main() { let main_window = MainWindow::new().unwrap(); // 获取文本的自然宽度 let text_width = main_window.get_text_natural_width(); let mut offset_x = main_window.get_offset_x(); // 启动定时更新线程(约60帧/秒) std::thread::spawn(move || { loop { std::thread::sleep(std::time::Duration::from_millis(16)); offset_x -= 1.0; // 当偏移量超过单个文本宽度时重置,实现无缝滚动 if offset_x < -text_width { offset_x = 0.0; } // 更新偏移量 main_window.set_offset_x(offset_x); } }); main_window.run().unwrap(); }
关键说明
natural-width是Slint组件的内置属性,会返回组件自动布局后的自然宽度,不会破坏自动布局逻辑。- 可视容器的
clip: true属性用于隐藏超出容器范围的文本,确保只显示滚动区域内的内容。 - 两个重复文本的设计是为了在滚动到末尾时,第二个文本能无缝衔接第一个文本的位置,避免出现空白间隙。
内容的提问来源于stack exchange,提问作者Jan Diederich
相关产品推荐
相关产品推荐

