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