Skip to content

Commit

Permalink
QML Features: Add constructor to nested qobjects
Browse files Browse the repository at this point in the history
  • Loading branch information
LeonMatthesKDAB committed Jul 6, 2023
1 parent e8b0c5d commit e964f88
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 26 deletions.
4 changes: 2 additions & 2 deletions examples/qml_features/qml/pages/NestedQObjectsPage.qml
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@ Page {
InnerObject {
id: innerObject
counter: 10

onCalled: () => console.warn("Inner signal called")
}

OuterObject {
id: outerObject
inner: innerObject

onCalled: (inner) => console.warn("Signal called, inner value: ", inner.counter)

Component.onCompleted: initialise()
}

Label {
Expand Down
61 changes: 40 additions & 21 deletions examples/qml_features/rust/src/nested_qobjects.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,6 @@ pub mod ffi {
}

unsafe extern "RustQt" {
/// Initialise the QObject, creating a connection from one signal to another
#[qinvokable]
fn initialise(self: Pin<&mut qobject::OuterObject>);

/// Print the count of the given inner QObject
//
// This method needs to be unsafe otherwise clippy complains that the
Expand All @@ -68,30 +64,15 @@ pub mod ffi {
#[qinvokable]
fn reset(self: Pin<&mut qobject::OuterObject>);
}

impl cxx_qt::Constructor<()> for qobject::OuterObject {}
}

use core::pin::Pin;

// TODO: this will change to qobject::OuterObject once
// https://github.com/KDAB/cxx-qt/issues/559 is done
impl ffi::OuterObjectQt {
/// Initialise the QObject, creating a connection from one signal to another
fn initialise(self: Pin<&mut Self>) {
// Example of connecting a signal from one QObject to another QObject
// this causes OuterObject::Called to trigger InnerObject::Called
self.on_called(|qobject, obj| {
// We need to convert the *mut T to a Pin<&mut T> so that we can reach the methods
if let Some(inner) = unsafe { qobject.inner().as_mut() } {
let pinned_inner = unsafe { Pin::new_unchecked(inner) };
// Now pinned inner can be used as normal
unsafe {
pinned_inner.called(obj);
}
}
})
.release();
}

/// Print the count of the given inner QObject
//
// This method needs to be unsafe otherwise clippy complains that the
Expand Down Expand Up @@ -120,4 +101,42 @@ impl ffi::OuterObjectQt {
unsafe { self.called(inner) };
}
}

impl cxx_qt::Constructor<()> for qobject::OuterObject {
type InitializeArguments = ();
type NewArguments = ();
type BaseArguments = ();

fn route_arguments(
_: (),
) -> (
Self::NewArguments,
Self::BaseArguments,
Self::InitializeArguments,
) {
((), (), ())
}

fn new(_: Self::NewArguments) -> <Self as cxx_qt::CxxQtType>::Rust {
Default::default()
}

/// Initialise the QObject, creating a connection from one signal to another
fn initialize(self: core::pin::Pin<&mut Self>, _: Self::InitializeArguments) {
// Example of connecting a signal from one QObject to another QObject
// this causes OuterObject::Called to trigger InnerObject::Called
self.on_called(|qobject, obj| {
// We need to convert the *mut T to a Pin<&mut T> so that we can reach the methods
if let Some(inner) = unsafe { qobject.inner().as_mut() } {
let pinned_inner = unsafe { Pin::new_unchecked(inner) };
// Now pinned inner can be used as normal
unsafe {
pinned_inner.called(obj);
}
}
})
.release();
}
}

// ANCHOR_END: book_macro_code
4 changes: 1 addition & 3 deletions examples/qml_features/tests/tst_nested_qobjects.qml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ TestCase {

Component {
id: componentOuterObject
OuterObject {
Component.onCompleted: initialise()
}
OuterObject { }
}

Component {
Expand Down

0 comments on commit e964f88

Please sign in to comment.