← Back to team overview

ubuntu-phone team mailing list archive

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

 

Can I use QList (or something similar) as Q_PROPERTY? How can I use it in
QML?

Best regards,
Nick


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

> CONSTANT (or whatever the name is) helps here as well -- if the prop does
> not change  :)
>
>
> On Wed, Oct 2, 2013 at 7:58 PM, Николай Шатохин <n.shatokhin@xxxxxxxxx>wrote:
>
>> Hm, yes, it helps. Thank you.
>>
>>
>> 2013/10/2 Roman Shchekin <mrqtros@xxxxxxxxx>
>>
>>> You should register Game via qmlRegisterType too.
>>>
>>> Your Engine's "game" property used in binding and it has no NOTIFY
>>> signal.
>>> I hope you know what is it. If no - you should learn basics of Qt first.
>>>
>>> Cheers,
>>> Roman.
>>>
>>>
>>> 2013/10/2 Николай Шатохин <n.shatokhin@xxxxxxxxx>
>>>
>>>> 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
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>
>>>>
>>>
>>
>> --
>> 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