← Back to team overview

ubuntu-phone team mailing list archive

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

 

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