← Back to team overview

ubuntu-phone team mailing list archive

Re: Create QML view for C++ object (not class)

 

I did it, but now I got:

QMetaProperty::read: Unable to handle unregistered datatype 'Game*' for
property 'Engine::game'

QQmlExpression: Expression qrc:/Reactor.qml:7 depends on non-NOTIFYable
properties:

Engine::game

On application startup (game is Q_PROPERY of Engine and has type Game *).


2013/10/2 Vladimir M. <mlvl.jr@xxxxxxxxx>

> Just put the star in the property decl -- it's the stock way to do it, and
> the decl w/o star will be deprecated probably soon, as far as I know. Then,
> bind to the props in qml, and that's it!
> 02 окт. 2013 г. 14:31 пользователь "Николай Шатохин" <
> n.shatokhin@xxxxxxxxx> написал:
>
>
>> Ok, I registered as Type class Ship inherited from QObject that have
>> fields:
>>
>> Q_PROPERTY(Hull hull READ hull)
>> Q_PROPERTY(Reactor reactor READ reactor)
>> Q_PROPERTY(Shields shields READ shields)
>>
>> (all field classes inherited from QObject too)
>>
>> But in ship class I'm using this fields as pointers (Hull * hull). So,
>> how to use correctly Q_Properties in this case? (I need call methods from
>> this fields and catch signals from them in QML)
>>
>>
>>
>> 2013/9/30 Vladimir M. <mlvl.jr@xxxxxxxxx>
>>
>>> Sure, you can always wire as many objects as possible to smth existing
>>> in a scene or set as a context property -- it's a simple Q_PROPERTY
>>> assignment on the C++ side, with a pointer passed to the setter (and works
>>> as soon as you declare the property on the QML side (or register and
>>> instantiate a C++ implemented item)).
>>>
>>> After all, these are ordinary QObejcts passing pointers (to each other)
>>> to each other :)
>>> (plus some memory management -- automatic on the QML side, and QObject
>>> parent-tree based on the C++ side)
>>>
>>> Vladimir
>>>
>>>
>>> On Mon, Sep 30, 2013 at 6:24 PM, Николай Шатохин <n.shatokhin@xxxxxxxxx>wrote:
>>>
>>>> What if I will create property backend in QML type and then I will set
>>>> this property in all QML objects to global object? So, theoretically this
>>>> can solve my problem.
>>>>
>>>>
>>>> 2013/9/30 Vladimir M. <mlvl.jr@xxxxxxxxx>
>>>>
>>>> Then, it looks like the standard way would be to have an instance of
>>>>> the item embedded in each page in the stack.
>>>>>
>>>>> If this turns out to be too resource consuming, you may try to play
>>>>> some tricks like removing it from all the pages and overlaying over the
>>>>> whole stack (if the item will always be in the same place, and have the
>>>>> same geometry, this will be rather simple, children order or z-value will
>>>>> allow it place it on top).
>>>>>
>>>>> If geometry is different for each page, this may get trickier
>>>>> (ultimate solution may be some sort of a "placeholder item" having the
>>>>> right place in each page, to which the item gets parented when the
>>>>> placeholder becomes visible, with "fill" anchoring).
>>>>>
>>>>> On the other hand, if the item has to have it's state consistent
>>>>> between the pages, then even if its is feasible performance-wise to embed
>>>>> it into all of them, some sort of common "view state model" should probably
>>>>> exist, and this again suggests just using a single instance...
>>>>>
>>>>> Vladimir
>>>>>
>>>>>
>>>>> On Mon, Sep 30, 2013 at 3:07 PM, Николай Шатохин <
>>>>> n.shatokhin@xxxxxxxxx> wrote:
>>>>>
>>>>>> I need to have this object in different qml files (for i.e. GameChat
>>>>>> must be shown on GameCreation,Game,GameResults pages: this it differents
>>>>>> QML files and differents pages in PageStack), but I created only one
>>>>>> QtQuickView in main.cpp. So, do view is qml file or QtQuckView object?
>>>>>>
>>>>>>
>>>>>> 2013/9/30 Vladimir M. <mlvl.jr@xxxxxxxxx>
>>>>>>
>>>>>> You probably can't share a single instance of a QML visual item
>>>>>>> between views, but as soon as you have the type registered properly /
>>>>>>> importable / etc, you can use instantiate it in as many views as you like.
>>>>>>> A QObject pointer can be passed around to items living in different
>>>>>>> veiws inside the same application, of course (but watch out for memory
>>>>>>> management issues -- see CppOwnership / QMLOwnership  / etc in the docs
>>>>>>> under "memory management").
>>>>>>>
>>>>>>> Easiest way may be to set the same object as a context prop for
>>>>>>> several views (unless you have some objections to this practice, like ones
>>>>>>> mentioned up in the thread).
>>>>>>>
>>>>>>> Lastly, there is that (legitimate) trick allowing QML items to be
>>>>>>> "rendered" by other items, resulting in the same item being shown in
>>>>>>> multiple places of the same scene (but being manipalatable anywhere except
>>>>>>> its actual position) -- look into the shader effects and such.
>>>>>>>
>>>>>>>
>>>>>>> On Mon, Sep 30, 2013 at 2:34 PM, Николай Шатохин <
>>>>>>> n.shatokhin@xxxxxxxxx> wrote:
>>>>>>>
>>>>>>>> What if I need to show the same QML object in two different places?
>>>>>>>> How to do this? How to create new QML object without recreating it in C++?
>>>>>>>>
>>>>>>>>
>>>>>>>> 2013/9/30 Николай Шатохин <n.shatokhin@xxxxxxxxx>
>>>>>>>>
>>>>>>>>> 0_o. I didn't know that all objects in QML are global. Thank you
>>>>>>>>> very much.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> 2013/9/30 <mrqtros@xxxxxxxxx>
>>>>>>>>>
>>>>>>>>>  Omg declare global engine object in main qml file and that's all
>>>>>>>>>>
>>>>>>>>>> 30.09.13 13:19 Николай Шатохин написал(а):
>>>>>>>>>> I'm using qmlRegisterType now. I have problems, because two QML
>>>>>>>>>> objects in different QML files it is two different objects in C++. I
>>>>>>>>>> registered as type class that have static object of Engine, but now I have
>>>>>>>>>> butthurt with it (I need retranslate all signals, getters and setters)
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> 2013/9/30 Michael Zanetti <michael.zanetti@xxxxxxxxxxxxx>
>>>>>>>>>>
>>>>>>>>>>> On Monday 30 September 2013 12:05:03 Николай Шатохин wrote:
>>>>>>>>>>> > Can I set only one object as context property that contains
>>>>>>>>>>> other objects
>>>>>>>>>>> > (and this objects contain objects too) and get this deep
>>>>>>>>>>> objects in QML?
>>>>>>>>>>> >
>>>>>>>>>>> > For i.e. I have object of class Engine that has object of
>>>>>>>>>>> class Game, Game
>>>>>>>>>>> > contains object of Ship and Ship contains object of Reactor.
>>>>>>>>>>> So, I set
>>>>>>>>>>> > object of Engine as context property and in QML write:
>>>>>>>>>>> >
>>>>>>>>>>> > engine.game.ship.reactor
>>>>>>>>>>> >
>>>>>>>>>>> > Can I use it?
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> Yes, given that "game" is a Q_PROPERTY() of "enigne", "ship" is
>>>>>>>>>>> a Q_PROPERTY()
>>>>>>>>>>> of "game" etc...
>>>>>>>>>>>
>>>>>>>>>>> Still, I recommend to register the type of the Engine instead of
>>>>>>>>>>> setting it as
>>>>>>>>>>> a context property.
>>>>>>>>>>>
>>>>>>>>>>> It's really just using qmlRegisterType() instead of
>>>>>>>>>>> setContextProperty(). It's
>>>>>>>>>>> not more or more complex code, but gives you better ways of
>>>>>>>>>>> structuring your
>>>>>>>>>>> QML code.
>>>>>>>>>>>
>>>>>>>>>>> >
>>>>>>>>>>> >
>>>>>>>>>>> > 2013/9/30 Николай Шатохин <n.shatokhin@xxxxxxxxx>
>>>>>>>>>>> >
>>>>>>>>>>> > > I've already found this solution:
>>>>>>>>>>> > >
>>>>>>>>>>> http://qt-project.org/doc/qt-5.0/qtqml/qtqml-cppintegration-contextpropert
>>>>>>>>>>> > > ies.html It helps. Thanks.
>>>>>>>>>>> > >
>>>>>>>>>>> > >
>>>>>>>>>>> > > 2013/9/30 Michael Zanetti <michael.zanetti@xxxxxxxxxxxxx>
>>>>>>>>>>> > >
>>>>>>>>>>> > >> On Sunday 29 September 2013 13:45:01 Vladimir M. wrote:
>>>>>>>>>>> > >> > Sounds like a "context property" use case (you plain set
>>>>>>>>>>> a QObject as a
>>>>>>>>>>> > >> > context property for a view's root scope, w/o even
>>>>>>>>>>> registering the
>>>>>>>>>>> > >>
>>>>>>>>>>> > >> object's
>>>>>>>>>>> > >>
>>>>>>>>>>> > >> > type, and all its properties and invokables become
>>>>>>>>>>> available).
>>>>>>>>>>> > >>
>>>>>>>>>>> > >> I don't recommend using context properties. While they are
>>>>>>>>>>> useful for
>>>>>>>>>>> > >> some
>>>>>>>>>>> > >> cases, this one doesn't seem to be one of those. Using too
>>>>>>>>>>> many global
>>>>>>>>>>> > >> context
>>>>>>>>>>> > >> properties can make the code very ugly to work with.
>>>>>>>>>>> > >>
>>>>>>>>>>> > >> You probably want to create something like this:
>>>>>>>>>>> > >>
>>>>>>>>>>> > >> class ViewController: public QObject
>>>>>>>>>>> > >> {
>>>>>>>>>>> > >>
>>>>>>>>>>> > >>   Q_PROPERTY(QList<MyClass> viewObjects READ viewObjects
>>>>>>>>>>> NOTIFY
>>>>>>>>>>> > >>
>>>>>>>>>>> > >> viewObjectsChanged)
>>>>>>>>>>> > >> ...
>>>>>>>>>>> > >> QList<MyClass> viewObjects() const {
>>>>>>>>>>> > >>
>>>>>>>>>>> > >>   return objectList;
>>>>>>>>>>> > >>
>>>>>>>>>>> > >> }
>>>>>>>>>>> > >> ...
>>>>>>>>>>> > >> };
>>>>>>>>>>> > >>
>>>>>>>>>>> > >> qmlRegisterType<ViewController>(uri, 0, 1,
>>>>>>>>>>> "ViewController");
>>>>>>>>>>> > >>
>>>>>>>>>>> > >> Then in QML you can do something like this:
>>>>>>>>>>> > >>
>>>>>>>>>>> > >> ViewController {
>>>>>>>>>>> > >>
>>>>>>>>>>> > >>   id: viewController
>>>>>>>>>>> > >>
>>>>>>>>>>> > >> }
>>>>>>>>>>> > >>
>>>>>>>>>>> > >> Repeater {
>>>>>>>>>>> > >>
>>>>>>>>>>> > >>   model: viewController.viewObjects
>>>>>>>>>>> > >>   MyView {
>>>>>>>>>>> > >>
>>>>>>>>>>> > >>     property var viewObject:
>>>>>>>>>>> viewController.viewObjects[index]
>>>>>>>>>>> > >>
>>>>>>>>>>> > >>   }
>>>>>>>>>>> > >>
>>>>>>>>>>> > >> }
>>>>>>>>>>> > >>
>>>>>>>>>>> > >>
>>>>>>>>>>> > >> Note that if you want your code to adjust more flexible
>>>>>>>>>>> (i.e. the
>>>>>>>>>>> > >> viewObjects
>>>>>>>>>>> > >> change a lot), consider using a QAbstractListModel (or some
>>>>>>>>>>> other model)
>>>>>>>>>>> > >> instead of a QList.
>>>>>>>>>>> > >>
>>>>>>>>>>> > >> Hope this helps,
>>>>>>>>>>> > >> Michael
>>>>>>>>>>> > >>
>>>>>>>>>>> > >> > On Sun, Sep 29, 2013 at 6:38 AM, Николай Шатохин
>>>>>>>>>>> > >>
>>>>>>>>>>> > >> <n.shatokhin@xxxxxxxxx>wrote:
>>>>>>>>>>> > >> > > Hello.
>>>>>>>>>>> > >> > >
>>>>>>>>>>> > >> > > When I create a class in C++, I can register it for QML
>>>>>>>>>>> and can
>>>>>>>>>>> > >> > > create
>>>>>>>>>>> > >> > > view for it. It's very convenient. But, if I need many
>>>>>>>>>>> objects of the
>>>>>>>>>>> > >>
>>>>>>>>>>> > >> same
>>>>>>>>>>> > >>
>>>>>>>>>>> > >> > > type, and need to show few views on screen, I got
>>>>>>>>>>> problems.
>>>>>>>>>>> > >> > > Is it possible to register QML type for object, not for
>>>>>>>>>>> class?
>>>>>>>>>>> > >> > > If I change some object, I need to see only its view
>>>>>>>>>>> changed.
>>>>>>>>>>> > >> > >
>>>>>>>>>>> > >> > > Best regard,
>>>>>>>>>>> > >> > > Nick
>>>>>>>>>>> > >> > >
>>>>>>>>>>> > >> > > --
>>>>>>>>>>> > >> > > Mailing list: https://launchpad.net/~ubuntu-phone
>>>>>>>>>>> > >> > > Post to     : ubuntu-phone@xxxxxxxxxxxxxxxxxxx
>>>>>>>>>>> > >> > > Unsubscribe : https://launchpad.net/~ubuntu-phone
>>>>>>>>>>> > >> > > More help   : https://help.launchpad.net/ListHelp
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>> --
>>>>>>>> Mailing list: https://launchpad.net/~ubuntu-phone
>>>>>>>> Post to     : ubuntu-phone@xxxxxxxxxxxxxxxxxxx
>>>>>>>> Unsubscribe : https://launchpad.net/~ubuntu-phone
>>>>>>>> More help   : https://help.launchpad.net/ListHelp
>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>

Follow ups

References