From e6977cb0f9adffea6509de9e052f59c9b21fc3c7 Mon Sep 17 00:00:00 2001 From: Andrew Hayzen Date: Tue, 16 Apr 2024 17:13:30 +0100 Subject: [PATCH 1/2] cxx-qt-lib-extras: add QPushButton --- .../include/gui/qpushbutton.h | 10 ++++ crates/cxx-qt-lib-extras-headers/src/lib.rs | 4 ++ crates/cxx-qt-lib-extras/build.rs | 2 + crates/cxx-qt-lib-extras/src/gui/mod.rs | 3 ++ .../cxx-qt-lib-extras/src/gui/qpushbutton.cpp | 8 +++ .../cxx-qt-lib-extras/src/gui/qpushbutton.rs | 51 +++++++++++++++++++ 6 files changed, 78 insertions(+) create mode 100644 crates/cxx-qt-lib-extras-headers/include/gui/qpushbutton.h create mode 100644 crates/cxx-qt-lib-extras/src/gui/qpushbutton.cpp create mode 100644 crates/cxx-qt-lib-extras/src/gui/qpushbutton.rs diff --git a/crates/cxx-qt-lib-extras-headers/include/gui/qpushbutton.h b/crates/cxx-qt-lib-extras-headers/include/gui/qpushbutton.h new file mode 100644 index 000000000..4e59c21c4 --- /dev/null +++ b/crates/cxx-qt-lib-extras-headers/include/gui/qpushbutton.h @@ -0,0 +1,10 @@ +// clang-format off +// SPDX-FileCopyrightText: 2023 Klarälvdalens Datakonsult AB, a KDAB Group company +// clang-format on +// SPDX-FileContributor: Andrew Hayzen +// +// SPDX-License-Identifier: MIT OR Apache-2.0 + +#pragma once + +#include diff --git a/crates/cxx-qt-lib-extras-headers/src/lib.rs b/crates/cxx-qt-lib-extras-headers/src/lib.rs index 45214b91a..45aa4a4e1 100644 --- a/crates/cxx-qt-lib-extras-headers/src/lib.rs +++ b/crates/cxx-qt-lib-extras-headers/src/lib.rs @@ -26,6 +26,10 @@ pub fn build_opts() -> cxx_qt_build::CxxQtBuildersOpts { include_str!("../include/gui/qapplication.h"), "qapplication.h", ), + ( + include_str!("../include/gui/qpushbutton.h"), + "qpushbutton.h", + ), ] { opts = opts.header(file_contents, "cxx-qt-lib-extras", file_name); } diff --git a/crates/cxx-qt-lib-extras/build.rs b/crates/cxx-qt-lib-extras/build.rs index 7e6b9c6aa..261ea88a6 100644 --- a/crates/cxx-qt-lib-extras/build.rs +++ b/crates/cxx-qt-lib-extras/build.rs @@ -13,6 +13,7 @@ fn main() { "core/qcommandlineoption", "core/qcommandlineparser", "gui/qapplication", + "gui/qpushbutton", ]; for rust_source in &rust_bridges { @@ -24,6 +25,7 @@ fn main() { "core/qcommandlineoption", "core/qcommandlineparser", "gui/qapplication", + "gui/qpushbutton", ]; builder = builder.cc_builder(move |cc| { diff --git a/crates/cxx-qt-lib-extras/src/gui/mod.rs b/crates/cxx-qt-lib-extras/src/gui/mod.rs index 44da642f5..ceb0f2856 100644 --- a/crates/cxx-qt-lib-extras/src/gui/mod.rs +++ b/crates/cxx-qt-lib-extras/src/gui/mod.rs @@ -5,3 +5,6 @@ mod qapplication; pub use qapplication::QApplication; + +mod qpushbutton; +pub use qpushbutton::QPushButton; diff --git a/crates/cxx-qt-lib-extras/src/gui/qpushbutton.cpp b/crates/cxx-qt-lib-extras/src/gui/qpushbutton.cpp new file mode 100644 index 000000000..4107fcc7f --- /dev/null +++ b/crates/cxx-qt-lib-extras/src/gui/qpushbutton.cpp @@ -0,0 +1,8 @@ +// clang-format off +// SPDX-FileCopyrightText: 2024 Klarälvdalens Datakonsult AB, a KDAB Group company +// clang-format on +// SPDX-FileContributor: Andrew Hayzen +// +// SPDX-License-Identifier: MIT OR Apache-2.0 + +#include "cxx-qt-lib-extras/qpushbutton.h" diff --git a/crates/cxx-qt-lib-extras/src/gui/qpushbutton.rs b/crates/cxx-qt-lib-extras/src/gui/qpushbutton.rs new file mode 100644 index 000000000..8dc35d593 --- /dev/null +++ b/crates/cxx-qt-lib-extras/src/gui/qpushbutton.rs @@ -0,0 +1,51 @@ +// SPDX-FileCopyrightText: 2024 Klarälvdalens Datakonsult AB, a KDAB Group company +// SPDX-FileContributor: Andrew Hayzen +// +// SPDX-License-Identifier: MIT OR Apache-2.0 + +#[cxx_qt::bridge(cxx_file_stem = "qpushbutton")] +mod ffi { + unsafe extern "C++" { + include!("cxx-qt-lib/qstring.h"); + type QString = cxx_qt_lib::QString; + } + + unsafe extern "C++Qt" { + include!("cxx-qt-lib-extras/qpushbutton.h"); + + #[qobject] + type QPushButton; + + // TODO: we should use upcasting methods here and implement QAbstractButton and QWidget + // so that we don't need to duplicate all of the methods + + /// This signal is emitted when the button is activated (i.e., pressed down then released while the mouse cursor is inside the button) + #[qsignal] + #[allow(dead_code)] + fn clicked(self: Pin<&mut QPushButton>, checked: bool); + + /// Set the text shown on the button + #[rust_name = "set_text"] + fn setText(self: Pin<&mut QPushButton>, text: &QString); + + /// Shows the widget and its child widgets. + fn show(self: Pin<&mut QPushButton>); + } + + #[namespace = "rust::cxxqtlib1"] + unsafe extern "C++Qt" { + include!("cxx-qt-lib/common.h"); + + #[doc(hidden)] + #[rust_name = "qpushbutton_init_default"] + fn make_unique() -> UniquePtr; + } +} + +impl ffi::QPushButton { + pub fn new() -> cxx::UniquePtr { + ffi::qpushbutton_init_default() + } +} + +pub use ffi::QPushButton; From dae15d92b22e45a4d93a65bd72b4ad65bc3d4910 Mon Sep 17 00:00:00 2001 From: Andrew Hayzen Date: Tue, 25 Jul 2023 15:04:42 +0100 Subject: [PATCH 2/2] examples: add basic widgets example --- Cargo.toml | 1 + .../cxx-qt-lib-extras/src/gui/qpushbutton.rs | 3 ++ examples/widgets_minimal/Cargo.toml | 28 +++++++++++++++ examples/widgets_minimal/build.rs | 15 ++++++++ examples/widgets_minimal/src/main.rs | 35 +++++++++++++++++++ 5 files changed, 82 insertions(+) create mode 100644 examples/widgets_minimal/Cargo.toml create mode 100644 examples/widgets_minimal/build.rs create mode 100644 examples/widgets_minimal/src/main.rs diff --git a/Cargo.toml b/Cargo.toml index 805948259..196f4b4c2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ members = [ "examples/demo_threading/rust", "examples/qml_features/rust", "examples/qml_minimal/rust", + "examples/widgets_minimal", "tests/basic_cxx_only/rust", "tests/basic_cxx_qt/rust", diff --git a/crates/cxx-qt-lib-extras/src/gui/qpushbutton.rs b/crates/cxx-qt-lib-extras/src/gui/qpushbutton.rs index 8dc35d593..86c1f9b74 100644 --- a/crates/cxx-qt-lib-extras/src/gui/qpushbutton.rs +++ b/crates/cxx-qt-lib-extras/src/gui/qpushbutton.rs @@ -43,6 +43,9 @@ mod ffi { } impl ffi::QPushButton { + // TODO: we need to think about how ownership in widgets is going to work + // as for items like QPushButton you may have a parent and have that + // free the object and not when the unique ptr goes out of scope pub fn new() -> cxx::UniquePtr { ffi::qpushbutton_init_default() } diff --git a/examples/widgets_minimal/Cargo.toml b/examples/widgets_minimal/Cargo.toml new file mode 100644 index 000000000..fe7a6255c --- /dev/null +++ b/examples/widgets_minimal/Cargo.toml @@ -0,0 +1,28 @@ +# SPDX-FileCopyrightText: 2024 Klarälvdalens Datakonsult AB, a KDAB Group company +# SPDX-FileContributor: Andrew Hayzen +# +# SPDX-License-Identifier: MIT OR Apache-2.0 + +[package] +name = "widgets-minimal-no-cmake" +version = "0.1.0" +authors = [ + "Andrew Hayzen ", + "Be Wilson ", + "Gerhard de Clercq ", + "Leon Matthes " +] +edition = "2021" +license = "MIT OR Apache-2.0" + +[dependencies] +cxx.workspace = true +cxx-qt.workspace = true +cxx-qt-lib.workspace = true +cxx-qt-lib-extras.workspace = true + +[build-dependencies] +# The link_qt_object_files feature is required for statically linking Qt 6. +cxx-qt-build = { workspace = true, features = [ "link_qt_object_files" ] } +cxx-qt-lib-headers.workspace = true +cxx-qt-lib-extras-headers.workspace = true diff --git a/examples/widgets_minimal/build.rs b/examples/widgets_minimal/build.rs new file mode 100644 index 000000000..bdd5a8e50 --- /dev/null +++ b/examples/widgets_minimal/build.rs @@ -0,0 +1,15 @@ +// SPDX-FileCopyrightText: 2024 Klarälvdalens Datakonsult AB, a KDAB Group company +// SPDX-FileContributor: Andrew Hayzen +// +// SPDX-License-Identifier: MIT OR Apache-2.0 + +use cxx_qt_build::CxxQtBuilder; + +fn main() { + CxxQtBuilder::new() + // Link Qt's Network library + .qt_module("Network") + .with_opts(cxx_qt_lib_headers::build_opts()) + .with_opts(cxx_qt_lib_extras_headers::build_opts()) + .build(); +} diff --git a/examples/widgets_minimal/src/main.rs b/examples/widgets_minimal/src/main.rs new file mode 100644 index 000000000..635088cbe --- /dev/null +++ b/examples/widgets_minimal/src/main.rs @@ -0,0 +1,35 @@ +// SPDX-FileCopyrightText: 2024 Klarälvdalens Datakonsult AB, a KDAB Group company +// SPDX-FileContributor: Andrew Hayzen +// +// SPDX-License-Identifier: MIT OR Apache-2.0 + +//! This example provides demostrations of building a Qt Widgets CXX-Qt application + +use cxx_qt_lib::QString; +use cxx_qt_lib_extras::{QApplication, QPushButton}; + +fn main() { + let mut app = QApplication::new(); + + // TODO: we should really pass a parent in here + let mut push_button = QPushButton::new(); + + if let Some(mut push_button) = push_button.as_mut() { + push_button + .as_mut() + .set_text(&QString::from("Hello World!")); + + push_button + .as_mut() + .on_clicked(|_, _| { + println!("Button Clicked!"); + }) + .release(); + + push_button.show(); + } + + if let Some(app) = app.as_mut() { + app.exec(); + } +}