Skip to content

Commit af971db

Browse files
aeynoogoffart
authored andcommitted
adding an example to illustrate custom QObject nesting
1 parent 4a661a4 commit af971db

File tree

4 files changed

+109
-0
lines changed

4 files changed

+109
-0
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,5 @@ members = [
99
'examples/todos',
1010
'examples/webengine',
1111
'examples/qenum',
12+
'examples/nested_qobjects',
1213
]

examples/nested_qobjects/Cargo.toml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[package]
2+
name = "nested_qobjects"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[dependencies]
9+
qmetaobject = { path = "../../qmetaobject" }
10+
cstr = "0.2"

examples/nested_qobjects/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Nested QObjects
2+
3+
This example illustrate how to put a `QObject` inside another `QObject` using `RefCell`.

examples/nested_qobjects/src/main.rs

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
use cstr::cstr;
2+
use qmetaobject::{
3+
qml_register_type, qt_base_class, qt_method, qt_property, qt_signal, QObject, QString,
4+
QmlEngine,
5+
};
6+
use std::cell::RefCell;
7+
8+
// Here we define a custom QObject Person with a property and two methods.
9+
#[derive(QObject, Default)]
10+
struct Person {
11+
base: qt_base_class!(trait QObject),
12+
name: qt_property!(QString; NOTIFY name_changed),
13+
name_changed: qt_signal!(),
14+
}
15+
16+
impl Person {
17+
fn set_name(&mut self, name: String) {
18+
self.name = name.into();
19+
self.name_changed();
20+
}
21+
22+
fn get_name(&self) -> String {
23+
self.name.to_string()
24+
}
25+
}
26+
27+
// Now we want to use the Person as a property of another QObject.
28+
#[derive(QObject, Default)]
29+
struct Greeter {
30+
base: qt_base_class!(trait QObject),
31+
32+
// To store our Person QObject as a property of another QObject, we need to use a RefCell.
33+
person: qt_property!(RefCell<Person>; NOTIFY person_changed),
34+
person_changed: qt_signal!(),
35+
36+
compute_greetings: qt_method!(
37+
fn compute_greetings(&self, verb: String) -> QString {
38+
// To access the person, we need to borrow it.
39+
format!("{} {}", verb, self.person.borrow().get_name()).into()
40+
}
41+
),
42+
set_person_name: qt_method!(
43+
fn set_person_name(&mut self, name: String) {
44+
// To modify the nested object we need to borrow it as mutable
45+
println!("Person name set to {}", &name);
46+
self.person.borrow_mut().set_name(name);
47+
self.person_changed();
48+
}
49+
),
50+
}
51+
52+
fn main() {
53+
// We need to register our two custom QObjects with the QML engine.
54+
qml_register_type::<Greeter>(cstr!("Greeter"), 1, 0, cstr!("Greeter"));
55+
qml_register_type::<Person>(cstr!("Person"), 1, 0, cstr!("Person"));
56+
57+
let mut engine = QmlEngine::new();
58+
engine.load_data(
59+
r#"
60+
import QtQuick 2.6
61+
import QtQuick.Window 2.0
62+
import Greeter 1.0
63+
64+
Window {
65+
visible: true
66+
Greeter {
67+
id: greeter;
68+
// Here we can directly set the person name inside the Greeter's Person property
69+
person.name: "World"
70+
// or we can use the set_person_name method to set the name
71+
//Component.onCompleted : {
72+
// greeter.set_person_name("foo");
73+
//}
74+
}
75+
Text {
76+
id: txt
77+
anchors.centerIn: parent
78+
text: greeter.compute_greetings("hello")
79+
80+
// When the person's name changes, we update the text
81+
Connections {
82+
target: greeter
83+
function onPersonChanged() {
84+
txt.text = greeter.compute_greetings("hello")
85+
}
86+
}
87+
}
88+
89+
90+
}
91+
"#
92+
.into(),
93+
);
94+
engine.exec();
95+
}

0 commit comments

Comments
 (0)