← Back to team overview

ubuntu-phone team mailing list archive

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

 

Can I use QList of pointers? And get objects in QML.


2013/10/7 Николай Шатохин <n.shatokhin@xxxxxxxxx>

> 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