← Back to team overview

ubuntu-phone team mailing list archive

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

 

Дружище, ты меня прости, что я по-русски тебе отвечу, но ты не желаешь пробовать, прежде чем спрашивать? Или просто документацию посмотреть? А то это спам какой-то уже!

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








Follow ups

References