Slint 的函數使用functions
關鍵字聲明。每個函數包括作用域(public、protected、private),聲明關鍵字(function),函數名, 以及參數和返回,函數的聲明格式與 Rust 類似,如下所示
export component Example {
in-out property min;
in-out property max;
protected function set-bounds(min: int, max: int) {
root.min = min;
root.max = max
}
public pure function inbound(x: int) -> int {
return Math.min(root.max, Math.max(root.min, x));
}
}
函數的返回在符號->
后指定返回類型,如果沒有顯式指定返回值,則默認返回最后一條語句的值。函數作用域默認是private
,效果與C++中的語法一致。因此:
private
只能在組件內使用protected
可以在繼承的組件中使用private
可以在其他外部組件中使用
如果函數在作用域后添加pure
關鍵字,則該函數為純函數,意味著該函數可以被其他屬性綁定或被其他組件或后臺語言的函數調用,但是無法修改環境中的屬性,同時用其綁定的屬性也不會更新屬性值。Slint 的callback
接口聲明為其他語言實現的函數接口,該接口在其他語言環境中實現,但只能在 Slint 界面中調用。即Rust
將負責實現 callback
然后被 Slint 調用,Rust 不能調用該接口。對于函數和回調的區別,以及pure修飾后的區別,也許有點難理解,看以下代碼即可明白:Slint 界面如下
import { Button, VerticalBox } from "std-widgets.slint";
export component AppWindow inherits Window {
width: 480px;
height: 272px;
in-out property counter: 0;
callback request_increase_value();
// 純函數可以調用屬性
public pure function get_counter() -> int{
// request_increase_value(); //不能調用其他非 pure 類型
// add_counter(); //不能調用其他非 pure 類型
root.counter
}
public function add_counter(){
root.counter += 1
}
// in-out property id : self.get_id(); //不能編譯通過
public function get_id() -> int{
2
}
in-out property age: self.request_age();
pure callback request_age() -> int;
in-out property id: 0;
// 純函數不能修改屬性
public pure function id_add() {
// root.id = root.id+1. //編譯無法通過
}
VerticalBox {
alignment: LayoutAlignment.center;
Text {
text: "Counter: \{root.counter}";
horizontal-alignment: TextHorizontalAlignment.center;
}
Text {
text: "Age: \{root.age}";
horizontal-alignment: TextHorizontalAlignment.center;
}
Button {
text: "Click";
clicked => {
// pure callback
root.request_age();
// callback
root.request_increase_value();
// function
root.add_counter();
}
}
}
}
Rust 后臺如下
slint::include_modules!();
fn main() -> Result<(), slint::PlatformError> {
let ui = AppWindow::new()?;
ui.on_request_increase_value({
let ui_handle = ui.as_weak();
move || {
let ui = ui_handle.unwrap();
ui.set_counter(ui.get_counter() + 1);
}
});
let mut age: i32 = 0;
ui.on_request_age({
let ui_handle = ui.as_weak();
move || {
let ui = ui_handle.unwrap();
println!("age: {age}");
age += 1;
// 返回請求值
age
}
});
ui.run()
}
初始界面
點擊 10 次按鈕后效果如下:
同時后臺打印
在每次點擊按鈕后,會進入按鈕的點擊響應邏輯
clicked => {
// pure callback
root.request_age();
// callback
root.request_increase_value();
// function
root.add_counter();
}
由于Counter
的怎普通的 Slint 函數add_counter
和普通的回調函數request_increase_value
中都會自加 1,因此最后Counter
的值顯示為 20。而age
的值則由pure
回調接口綁定,因此即使每次回調接口被調用了,但返回值也沒有更新到age
屬性。基于以上代碼可以體驗到以下幾點
- Slint 函數在 Slint 文件中定義和實現
- 回調接口 Slint 中聲明,但在 Rust 或其他語言中實現。
- 函數和回調接口都是在Slint 中被調用, 不能直接在 Rust 中調用。
- Pure 函數或接口只能調用 Pure 函數或接口,不能調用其他非 Pure 類型。
ui.on_request_age({
let ui_handle = ui.as_weak();
move || {
let ui = ui_handle.unwrap();
println!("age: {age}");
age += 1;
// 返回請求值
println!("request age: {}", ui.invoke_request_age());
//
ui.invoke_add_counter();
age
}
});