← Back to team overview

ubuntu-phone team mailing list archive

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

 

But game property is a pointer. I don't think that it will change its
address in runtime.


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
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>
>>
>

References