Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unresolved imports QGuiApplication, QQmlApplicationEngine when building with Cargo on Windows #1148

Closed
Artalus opened this issue Dec 22, 2024 · 4 comments
Labels
🚫🪲 Not a bug This is working as intended - may need additional documentation

Comments

@Artalus
Copy link

Artalus commented Dec 22, 2024

I am following the Book and copypasting the code from there as I go. I am on Windows, so initially I ran into #1120 , but after switching to an Admin shell, I now get this:

PS D:\git\qtrs> cargo build
   Compiling link-cplusplus v1.0.9
   Compiling cxx v1.0.135
   Compiling cxx-qt v0.7.0
   Compiling cxx-qt-lib v0.7.0
   Compiling qtrs v0.1.0 (D:\git\qtrs)
error[E0432]: unresolved imports `cxx_qt_lib::QGuiApplication`, `cxx_qt_lib::QQmlApplicationEngine`
 --> src/main.rs:3:18
  |
3 | use cxx_qt_lib::{QGuiApplication, QQmlApplicationEngine, QUrl};
  |                  ^^^^^^^^^^^^^^^  ^^^^^^^^^^^^^^^^^^^^^ no `QQmlApplicationEngine` in the root
  |                  |
  |                  no `QGuiApplication` in the root
  |                  help: a similar name exists in the module: `QCoreApplication`

For more information about this error, try `rustc --explain E0432`.
error: could not compile `qtrs` (bin "qtrs") due to 1 previous error

My Cargo.toml:

[package]
name = "qtrs"
version = "0.1.0"
edition = "2021"

[dependencies]
cxx = "1.0.135"
cxx-qt = "0.7.0"
cxx-qt-lib = "0.7.0"

[build-dependencies]
# The link_qt_object_files feature is required for statically linking Qt 6.
cxx-qt-build = { version = "0.7.0", features = [ "link_qt_object_files" ] }

The only difference from https://kdab.github.io/cxx-qt/book/getting-started/4-cargo-executable.html is that cxx is 1.0.135 instead of 1.0.95, but downgrading it does not change anything, as cargo keeps downloading 1.0.135 for some reason.

The copypasted contents from Book:

src\cxxqt_object.rs

/// The bridge definition for our QObject
#[cxx_qt::bridge]
pub mod qobject {

    unsafe extern "C++" {
        include!("cxx-qt-lib/qstring.h");
        /// An alias to the QString type
        type QString = cxx_qt_lib::QString;
    }

    unsafe extern "RustQt" {
        // The QObject definition
        // We tell CXX-Qt that we want a QObject class with the name MyObject
        // based on the Rust struct MyObjectRust.
        #[qobject]
        #[qml_element]
        #[qproperty(i32, number)]
        #[qproperty(QString, string)]
        #[namespace = "my_object"]
        type MyObject = super::MyObjectRust;
    }

    unsafe extern "RustQt" {
        // Declare the invokable methods we want to expose on the QObject
        #[qinvokable]
        #[cxx_name = "incrementNumber"]
        fn increment_number(self: Pin<&mut MyObject>);

        #[qinvokable]
        #[cxx_name = "sayHi"]
        fn say_hi(self: &MyObject, string: &QString, number: i32);
    }
}

use core::pin::Pin;
use cxx_qt_lib::QString;

/// The Rust struct for the QObject
#[derive(Default)]
pub struct MyObjectRust {
    number: i32,
    string: QString,
}

impl qobject::MyObject {
    /// Increment the number Q_PROPERTY
    pub fn increment_number(self: Pin<&mut Self>) {
        let previous = *self.number();
        self.set_number(previous + 1);
    }

    /// Print a log message with the given string and number
    pub fn say_hi(&self, string: &QString, number: i32) {
        println!("Hi from Rust! String is '{string}' and number is {number}");
    }
}

src\main.rs

pub mod cxxqt_object;

use cxx_qt_lib::{QGuiApplication, QQmlApplicationEngine, QUrl};

fn main() {
    // Create the application and engine
    let mut app = QGuiApplication::new();
    let mut engine = QQmlApplicationEngine::new();

    // Load the QML path into the engine
    if let Some(engine) = engine.as_mut() {
        engine.load(&QUrl::from("qrc:/qt/qml/com/kdab/cxx_qt/demo/qml/main.qml"));
    }

    if let Some(engine) = engine.as_mut() {
        // Listen to a signal from the QML Engine
        engine
            .as_qqmlengine()
            .on_quit(|_| {
                println!("QML Quit!");
            })
            .release();
    }

    // Start the app
    if let Some(app) = app.as_mut() {
        app.exec();
    }
}

build.rs

use cxx_qt_build::{CxxQtBuilder, QmlModule};

fn main() {
    CxxQtBuilder::new()
        // Link Qt's Network library
        // - Qt Core is always linked
        // - Qt Gui is linked by enabling the qt_gui Cargo feature of cxx-qt-lib.
        // - Qt Qml is linked by enabling the qt_qml Cargo feature of cxx-qt-lib.
        // - Qt Qml requires linking Qt Network on macOS
        .qt_module("Network")
        .qml_module(QmlModule {
            uri: "com.kdab.cxx_qt.demo",
            rust_files: &["src/cxxqt_object.rs"],
            qml_files: &["qml/main.qml"],
            ..Default::default()
        })
        .build();
}

@ubas-of-the-bush
Copy link

ubas-of-the-bush commented Dec 23, 2024

@Artalus

I just ran into this problem as well!

To solve it, you need to specify that you want all features of cxx-qt-lib: cxx-qt-lib = {version = "0.7.0", features = [ "full" ]}

Once I added that to my Cargo.toml, rust-analyser recognised those imports you mentioned, and it compiled fine.

The book also specifies the wrong feature flag in the reference Cargo.toml; it specifies cxx-qt-lib = { version="0.7", features = ["qt_full"] }, but cargo couldn't reconcile "qt_full" with version=^0.7.0 - perhaps the name was changed?

@redstrate
Copy link
Contributor

@Artalus

I just ran into this problem as well!

To solve it, you need to specify that you want all features of cxx-qt-lib: cxx-qt-lib = {version = "0.7.0", features = [ "full" ]}

Once I added that to my Cargo.toml, rust-analyser recognised those imports you mentioned, and it compiled fine.

The book also specifies the wrong feature flag in the reference Cargo.toml; it specifies cxx-qt-lib = { version="0.7", features = ["qt_full"] }, but cargo couldn't reconcile "qt_full" with version=^0.7.0 - perhaps the name was changed?

You probably only need qt_qml and qt_gui, not the rest of the features. We still have the qt_full feature, what's the error you get when using it?

@redstrate redstrate added the 🚫🪲 Not a bug This is working as intended - may need additional documentation label Dec 30, 2024
@ubas-of-the-bush
Copy link

Just tried and failed to reproduce the error I allegedly got when using the "qt_full" feature flag; my code, which is essentially the example in the book, compiled just fine with ["full"], ["qt_full"], and ["qt_qml", "qt_gui"] feature flags. Copy-and-pasting the Cargo.toml in the book also compiles fine.

(My bad, sorry - maybe I made a typo in the Cargo.toml and didn't notice?)

@LeonMatthesKDAB
Copy link
Collaborator

LeonMatthesKDAB commented Jan 10, 2025

Thank you @ubas-of-the-bush for following up on this.

This should be solved by enabling qt_full or another feature set that enables qt_qml and qt_gui, as you describe.
We may need to point this out more clearly in the documentation.

I will close the issue for now.

@Artalus if you still encounter the issue even after enabling the required features, please reopen the issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🚫🪲 Not a bug This is working as intended - may need additional documentation
Projects
None yet
Development

No branches or pull requests

4 participants