1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
// Copyright (C) 2026 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only
use qtbridge_type_lib::QObject;
use crate::QmlMethodInvoker;
use crate::qobjectholder::QObjectHolder;
use crate::registry::Owner;
pub trait QmlObject: QObjectHolder {
/// Creates a default-initialized instance and attaches its [`QObject`]
/// eagerly.
///
/// The returned `Rc<RefCell<Self>>` is an ordinary handle, shared with
/// QML. Droping the handle does not drop the instance if it is in use by
/// QML or until the garbage collection delete the QML instance.
fn default_with_attached_qobject() -> std::rc::Rc<std::cell::RefCell<Self>>
where
Self: Default,
{
let instance = Default::default();
Self::attach_qobject(&instance);
instance
}
/// Attaches a dedicated [`QObject`] to an existing `instance`,
/// enabling its use in QML.
fn attach_qobject(instance: &std::rc::Rc<std::cell::RefCell<Self>>) {
Self::register_instance(instance.clone(), Owner::RustRegistry, None);
}
/// Detaches and deletes the dedicated [`QObject`] of this instance.
///
/// The instance continues as a plain Rust value and heals with a
/// fresh [`QObject`] on its next exposure to QML.
fn detach_qobject(&self) {
let qobj_ptr = self.get_qobject_ptr();
if !qobj_ptr.is_null() {
QObject::delete(qobj_ptr);
}
}
/// Returns a [`QmlMethodInvoker`] that can invoke methods on the underlying
/// `QObject` from any thread.
///
/// # Example
///
/// ```
/// # use qtbridge::{qobject, QmlObject};
/// # #[qobject]
/// # pub mod example {
/// # #[derive(Default)]
/// # pub struct Backend {}
/// # impl Backend {
/// # #[qsignal]
/// # pub fn data_ready(&mut self);
/// # }
/// # }
/// # use example::Backend;
/// let backend = Backend::default_with_attached_qobject();
/// let invoker = backend.borrow().get_qml_method_invoker();
/// invoker.invoke_method("dataReady");
/// ```
fn get_qml_method_invoker(&self) -> QmlMethodInvoker
{
QmlMethodInvoker::new(self)
}
}
impl<T: QObjectHolder> QmlObject for T {}