mirror of
https://github.com/slint-ui/slint.git
synced 2025-08-03 18:29:09 +00:00
Python: Add the ability to invoke functions declared in Slint from Python
This commit is contained in:
parent
37b63e4bd4
commit
b98035526b
5 changed files with 65 additions and 3 deletions
|
@ -154,6 +154,11 @@ impl ComponentDefinition {
|
|||
self.definition.callbacks().collect()
|
||||
}
|
||||
|
||||
#[getter]
|
||||
fn functions(&self) -> Vec<String> {
|
||||
self.definition.functions().collect()
|
||||
}
|
||||
|
||||
#[getter]
|
||||
fn globals(&self) -> Vec<String> {
|
||||
self.definition.globals().collect()
|
||||
|
@ -169,6 +174,10 @@ impl ComponentDefinition {
|
|||
self.definition.global_callbacks(name).map(|callbackiter| callbackiter.collect())
|
||||
}
|
||||
|
||||
fn global_functions(&self, name: &str) -> Option<Vec<String>> {
|
||||
self.definition.global_functions(name).map(|functioniter| functioniter.collect())
|
||||
}
|
||||
|
||||
fn create(&self) -> Result<ComponentInstance, crate::errors::PyPlatformError> {
|
||||
Ok(ComponentInstance {
|
||||
instance: self.definition.create()?,
|
||||
|
|
|
@ -74,6 +74,22 @@ def _build_global_class(compdef, global_name):
|
|||
|
||||
properties_and_callbacks[python_prop] = mk_setter_getter(callback_name)
|
||||
|
||||
for function_name in compdef.global_functions(global_name):
|
||||
python_prop = _normalize_prop(function_name)
|
||||
if python_prop in properties_and_callbacks:
|
||||
logging.warning(f"Duplicated function {prop_name}")
|
||||
continue
|
||||
|
||||
def mk_getter(function_name):
|
||||
def getter(self):
|
||||
def call(*args):
|
||||
return self.__instance__.invoke_global(global_name, function_name, *args)
|
||||
return call
|
||||
|
||||
return property(getter)
|
||||
|
||||
properties_and_callbacks[python_prop] = mk_getter(function_name)
|
||||
|
||||
return type("SlintGlobalClassWrapper", (), properties_and_callbacks)
|
||||
|
||||
|
||||
|
@ -143,6 +159,22 @@ def _build_class(compdef):
|
|||
|
||||
properties_and_callbacks[python_prop] = mk_setter_getter(callback_name)
|
||||
|
||||
for function_name in compdef.functions:
|
||||
python_prop = _normalize_prop(function_name)
|
||||
if python_prop in properties_and_callbacks:
|
||||
logging.warning(f"Duplicated function {prop_name}")
|
||||
continue
|
||||
|
||||
def mk_getter(function_name):
|
||||
def getter(self):
|
||||
def call(*args):
|
||||
return self.__instance__.invoke(function_name, *args)
|
||||
return call
|
||||
|
||||
return property(getter)
|
||||
|
||||
properties_and_callbacks[python_prop] = mk_getter(function_name)
|
||||
|
||||
for global_name in compdef.globals:
|
||||
global_class = _build_global_class(compdef, global_name)
|
||||
|
||||
|
|
|
@ -3,7 +3,8 @@
|
|||
|
||||
import pytest
|
||||
from slint import slint as native
|
||||
from slint.slint import ValueType;
|
||||
from slint.slint import ValueType
|
||||
|
||||
|
||||
def test_basic_compiler():
|
||||
compiler = native.ComponentCompiler()
|
||||
|
@ -18,6 +19,7 @@ def test_basic_compiler():
|
|||
export global TestGlobal {
|
||||
in property <string> theglobalprop;
|
||||
callback globallogic();
|
||||
public function globalfun() {}
|
||||
}
|
||||
|
||||
export component Test {
|
||||
|
@ -31,6 +33,7 @@ def test_basic_compiler():
|
|||
in property <[string]> modelprop;
|
||||
|
||||
callback test-callback();
|
||||
public function ff() {}
|
||||
}
|
||||
""", "")
|
||||
assert compdef != None
|
||||
|
@ -38,21 +41,28 @@ def test_basic_compiler():
|
|||
assert compdef.name == "Test"
|
||||
|
||||
props = [(name, type) for name, type in compdef.properties.items()]
|
||||
assert props == [('boolprop', ValueType.Bool), ('brushprop', ValueType.Brush), ('colprop', ValueType.Brush), ('floatprop', ValueType.Number), ('imgprop', ValueType.Image), ('intprop', ValueType.Number), ('modelprop', ValueType.Model), ('strprop', ValueType.String)]
|
||||
assert props == [('boolprop', ValueType.Bool), ('brushprop', ValueType.Brush), ('colprop', ValueType.Brush), ('floatprop', ValueType.Number),
|
||||
('imgprop', ValueType.Image), ('intprop', ValueType.Number), ('modelprop', ValueType.Model), ('strprop', ValueType.String)]
|
||||
|
||||
assert compdef.callbacks == ["test-callback"]
|
||||
assert compdef.functions == ["ff"]
|
||||
|
||||
assert compdef.globals == ["TestGlobal"]
|
||||
|
||||
assert compdef.global_properties("Garbage") == None
|
||||
assert [(name, type) for name, type in compdef.global_properties("TestGlobal").items()] == [('theglobalprop', ValueType.String)]
|
||||
assert [(name, type) for name, type in compdef.global_properties(
|
||||
"TestGlobal").items()] == [('theglobalprop', ValueType.String)]
|
||||
|
||||
assert compdef.global_callbacks("Garbage") == None
|
||||
assert compdef.global_callbacks("TestGlobal") == ["globallogic"]
|
||||
|
||||
assert compdef.global_functions("Garbage") == None
|
||||
assert compdef.global_functions("TestGlobal") == ["globalfun"]
|
||||
|
||||
instance = compdef.create()
|
||||
assert instance != None
|
||||
|
||||
|
||||
def test_compiler_build_from_path():
|
||||
compiler = native.ComponentCompiler()
|
||||
|
||||
|
|
|
@ -35,8 +35,12 @@ def test_load_file_wrapper():
|
|||
instance.say_hello = lambda x: "from here: " + x
|
||||
assert instance.say_hello("wohoo") == "from here: wohoo"
|
||||
|
||||
assert instance.plus_one(42) == 43
|
||||
|
||||
assert instance.MyGlobal.global_prop == "This is global"
|
||||
|
||||
assert instance.MyGlobal.minus_one(100) == 99
|
||||
|
||||
del instance
|
||||
|
||||
|
||||
|
|
|
@ -4,6 +4,9 @@
|
|||
export global MyGlobal {
|
||||
in-out property <string> global-prop: "This is global";
|
||||
callback global-callback(string) -> string;
|
||||
public function minus-one(value: int) {
|
||||
return value - 1;
|
||||
}
|
||||
}
|
||||
|
||||
export component App {
|
||||
|
@ -26,6 +29,10 @@ export component App {
|
|||
return MyGlobal.global-callback(arg);
|
||||
}
|
||||
|
||||
public function plus-one(value: int) {
|
||||
return value + 1;
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
color: red;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue