Skip to content

Commit d1b99e3

Browse files
committed
cxx-qt-lib: use cxx_qt::bridge and #[qsignal] in QQmlEngine
This allows for us to declare a signal and listen to it.
1 parent 9309a94 commit d1b99e3

File tree

6 files changed

+56
-4
lines changed

6 files changed

+56
-4
lines changed

crates/cxx-qt-lib-headers/include/qml/qqmlapplicationengine.h

+4
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,17 @@
1111
#include <memory>
1212

1313
#include <QtQml/QQmlApplicationEngine>
14+
#include <QtQml/QQmlEngine>
1415

1516
namespace rust {
1617
namespace cxxqtlib1 {
1718

1819
::std::unique_ptr<QQmlApplicationEngine>
1920
qqmlapplicationengineNew();
2021

22+
QQmlEngine&
23+
qqmlapplicationengineAsQQmlEngine(QQmlApplicationEngine&);
24+
2125
}
2226
}
2327

crates/cxx-qt-lib/src/qml/qqmlapplicationengine.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,11 @@ qqmlapplicationengineNew()
1616
return ::std::make_unique<QQmlApplicationEngine>();
1717
}
1818

19+
QQmlEngine&
20+
qqmlapplicationengineAsQQmlEngine(QQmlApplicationEngine& engine)
21+
{
22+
return static_cast<QQmlEngine&>(engine);
23+
}
24+
1925
}
2026
}

crates/cxx-qt-lib/src/qml/qqmlapplicationengine.rs

+19
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,22 @@ mod ffi {
6161
fn setOfflineStoragePath(self: Pin<&mut QQmlApplicationEngine>, dir: &QString);
6262
}
6363

64+
unsafe extern "C++" {
65+
include!("cxx-qt-lib/qqmlengine.h");
66+
type QQmlEngine = crate::QQmlEngine;
67+
}
68+
6469
#[namespace = "rust::cxxqtlib1"]
6570
unsafe extern "C++" {
6671
#[doc(hidden)]
6772
#[rust_name = "qqmlapplicationengine_new"]
6873
fn qqmlapplicationengineNew() -> UniquePtr<QQmlApplicationEngine>;
74+
75+
#[doc(hidden)]
76+
#[rust_name = "qqmlapplicationengine_as_qqmlengine"]
77+
fn qqmlapplicationengineAsQQmlEngine(
78+
ptr: Pin<&mut QQmlApplicationEngine>,
79+
) -> Pin<&mut QQmlEngine>;
6980
}
7081

7182
// QQmlApplicationEngine is not a trivial to CXX and is not relocatable in Qt
@@ -75,9 +86,17 @@ mod ffi {
7586
impl UniquePtr<QQmlApplicationEngine> {}
7687
}
7788

89+
use crate::QQmlEngine;
90+
use core::pin::Pin;
91+
7892
pub use ffi::QQmlApplicationEngine;
7993

8094
impl QQmlApplicationEngine {
95+
/// Convert the existing [QQmlApplicationEngine] to a [cxx_qt_lib::QQmlEngine]
96+
pub fn as_qqmlengine<'a>(self: Pin<&'a mut Self>) -> Pin<&'a mut QQmlEngine> {
97+
ffi::qqmlapplicationengine_as_qqmlengine(self)
98+
}
99+
81100
/// Create a new QQmlApplicationEngine
82101
pub fn new() -> cxx::UniquePtr<Self> {
83102
ffi::qqmlapplicationengine_new()

crates/cxx-qt-lib/src/qml/qqmlengine.rs

+14-4
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,21 @@
33
//
44
// SPDX-License-Identifier: MIT OR Apache-2.0
55

6-
#[cxx::bridge]
6+
#[cxx_qt::bridge(cxx_file_stem = "qqmlengine")]
77
mod ffi {
8+
unsafe extern "C++Qt" {
9+
include!("cxx-qt-lib/qqmlengine.h");
10+
type QQmlEngine;
11+
12+
/// This signal is emitted when the QML loaded by the engine would like to exit from the event loop with the specified return code ret_code.
13+
#[qsignal]
14+
fn exit(self: Pin<&mut QQmlEngine>, ret_code: i32);
15+
16+
/// This signal is emitted when the QML loaded by the engine would like to quit.
17+
#[qsignal]
18+
fn quit(self: Pin<&mut QQmlEngine>);
19+
}
20+
821
unsafe extern "C++" {
922
include!("cxx-qt-lib/qstring.h");
1023
type QString = crate::QString;
@@ -13,9 +26,6 @@ mod ffi {
1326
include!("cxx-qt-lib/qurl.h");
1427
type QUrl = crate::QUrl;
1528

16-
include!("cxx-qt-lib/qqmlengine.h");
17-
type QQmlEngine;
18-
1929
/// Adds path as a directory where the engine searches for installed modules in a URL-based directory structure.
2030
#[rust_name = "add_import_path"]
2131
fn addImportPath(self: Pin<&mut QQmlEngine>, path: &QString);

examples/cargo_without_cmake/src/main.rs

+7
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@ fn main() {
2828
engine.load(&QUrl::from("qrc:/qt/qml/com/kdab/cxx_qt/demo/qml/main.qml"));
2929
}
3030

31+
if let Some(engine) = engine.as_mut() {
32+
// Listen to a signal from the QML Engine
33+
engine.as_qqmlengine().on_quit(|_| {
34+
println!("QML Quit!");
35+
});
36+
}
37+
3138
// Start the app
3239
if let Some(app) = app.as_mut() {
3340
app.exec();

examples/qml_minimal/qml/main.qml

+6
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ Window {
5151

5252
onClicked: myObject.sayHi(myObject.string, myObject.number)
5353
}
54+
55+
Button {
56+
text: qsTr("Quit")
57+
58+
onClicked: Qt.quit()
59+
}
5460
}
5561
}
5662
// ANCHOR_END: book_main_qml

0 commit comments

Comments
 (0)