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

Assigning/binding custom property types within qml. #29

Closed
Pfeil opened this issue Feb 26, 2019 · 5 comments
Closed

Assigning/binding custom property types within qml. #29

Pfeil opened this issue Feb 26, 2019 · 5 comments

Comments

@Pfeil
Copy link

Pfeil commented Feb 26, 2019

(I created a minimal example which may be helpful to take a closer look. This uses the normal qmetaobject version from crates.io. All code snippets here are excerpts from this repo.)

So I created two types inheriting from QQuickItem. One should be a property from the other. I've done this via a RefCell as you told me in #26 .

#[derive(Default, QObject)]
struct Slice {
    base: qt_base_class!(trait QQuickItem),
}

#[derive(Default, QObject)]
struct Pie {
    base: qt_base_class!(trait QQuickItem),
    slice: qt_property!(RefCell<Slice>; /*READ get_slice WRITE set_slice*/),
}

impl Pie {
    //fn get_slice(&self) -> RefCell<Slice> {
    //    self.slice // how?
    //}
    //fn set_slice(&mut self, s: RefCell<Slice>) {
    //    self.slice = s;
    //}
}
impl QQuickItem for Slice {}
impl QQuickItem for Pie {}

While this compiles, QML does throw runtime errors. This is the QML file (without imports):

ApplicationWindow {
    Slice {id: s}  // works
    Pie {}    // works

    // does not work:
    Pie {
        slice: s
    }

    // does not work:
    Pie {
        slice: Slice {}
    }
}

So, the following things do currently not work:

  1. binding the Slice to the Pie,
  2. binding the Slice to the Pie using an identifier,
  3. implementing a getter (and the setter may be garbage?).

From the tutorial and other qt docs I found, I was not able to derive whats wrong/missing, and in this area the examples and documentation of qmetaobject is getting thin. I'd love to work on the docs as soon as I finished what I began (and understand it ;) ).

@ogoffart
Copy link
Member

Thanks for reporting. I believe (not 100%sure) that the problem is that the Slice is registered twice as different QMetaType.

The first time it is register with you calling qml_register_type which you need to do to be able to use Slice {}
The second time, it is the impl<T> PropertyType for ::std::cell::RefCell<T> which registers again in register_metatype_qobject

Ideally, registering twice with the same name should merge both type internally within Qt. But apparently this is not the case. I'll try to have a look next week.

@Pfeil
Copy link
Author

Pfeil commented Feb 28, 2019

Thanks for looking into this. I just thought a little about how something like this could be tested. It would work either by using a timeout and a qml file which quits on completion, or by reading the stdout/err and recognizing errors or if there would be some kind of "crash on error" mode for the qml engine, but I could not find anything (it could maybe added into the wrapper, though). There is a warning() signal of the qml engine that can maybe hooked into. I'll see if I can find some time to look into that.

@ogoffart
Copy link
Member

ogoffart commented Mar 7, 2019

So the problem is, actually, that the RefCell property are in fact, read-only.
That's because this is not a pointer to the object, but the object itself.

Maybe one could also support QPointer or Rc or some kind of pointer to object as property. But this is not yet implemented.

@Guiguiprim
Copy link
Contributor

Support for QPointer property as just been added.

@VelorumS
Copy link

I'm trying to do something similar with QVariant: a listmodel that returns instances of another listmodel as data (which has to return QVariant`).

The object I get:

Property 'rowCount' of object QVariant(TypeId{t:101367805964437697995887911836490702384}, ) is not a function

The model I'm trying to return is similar to the SimpleListModel, I've tried both qml_register_type and register like that:

impl Clone for TagListModel {
    fn clone(&self) -> Self {
        Self::new()
    }
}

impl QMetaType for TagListModel {}

...

TagListModel::register(Some(&CString::new("TagListModel").unwrap()));

What's the equivalent of Q_DECLARE_METATYPE() to make this model fit in QVariant?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants