← Back to team overview

ubuntu-phone team mailing list archive

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

 

I surprised that guy named Vladimir doesn't know Russian :) Unfortunatelly,
I can't go to DevDays :(


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

> Hey, stop sending those cryptic messages! Not everyone understands Russin
> here!! :)
> Fact is, sometimes it's indeed easier to ask, with QML.
> And QML needs a better set of guides on C++ integration, also (btw, if
> anyone currently reading this is at DevDays these days, you can find me at
> ICS booth -- just near to where the Ubuntu guys are showing their stuff --
> and we can discuss some nice aspects of working with QML; and I'm also
> giving a talk!! :)).
>
>
> On Mon, Oct 7, 2013 at 1:07 PM, <mrqtros@xxxxxxxxx> wrote:
>
>>  Дружище, ты меня прости, что я по-русски тебе отвечу, но ты не желаешь
>> пробовать, прежде чем спрашивать? Или просто документацию посмотреть? А то
>> это спам какой-то уже!
>>
>>
>> Best regards,
>>
>> Roman.
>>
>> 07.10.13 13:12 Николай Шатохин написал(а):
>> 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
>>>>>
>>>>>
>>>>
>>>
>>
>

References