PDA

View Full Version : Use own Class in some Qt class



Ichi
2nd April 2013, 22:04
Hi,
I start with example: i have for example QQuickView class and i want set my own instance of QQuickItem but how i know one way:
implement own instance of QQuickView class and use own QQuickItem class. This is hard way and only way or is there some another way to do this?

wysota
2nd April 2013, 22:49
Please rephrase your question. It is hard to make out what you want.

anda_skoa
3rd April 2013, 15:30
Indeed hard to understand the problem, but my guess is you are looking for qmlRegisterType()?

Cheers,
_

Ichi
3rd April 2013, 15:31
ok i want use my own instance of QQuickItem in QQuickView. For example:
I make my class MyItem - public class Item : public QQuickItem
QQuickView *view = new QQuickView();
view->rootObject->itemsChild(); and i want that this will return QList<MyItem> items;

wysota
3rd April 2013, 16:58
Do you mean that you want to be able to put instances of your MyItem class into QtQuick scene or that all items in the scene are MyItem instances instead of QQuickItem instances?

Ichi
3rd April 2013, 19:22
all items in the scene are MyItem instances instead of QQuickItem instances
this is waht i want, sorry for hard understanding but i realy didn't know how say it :D

wysota
3rd April 2013, 19:31
In that case that is not possible. Why do you want that?

Ichi
3rd April 2013, 19:40
Because when i did one program i wanted to storage friend QQuickItem. I this case i have to use objectUserData method, but i think if i make own class it will much better but this is only one example this happen me few times

wysota
3rd April 2013, 19:44
Because when i did one program i wanted to storage friend QQuickItem.
I don't understand what it means.


I this case i have to use objectUserData method
Why do you have to use that method (whatever it is)? And what does QQuickItem have to do with this?

Ichi
3rd April 2013, 19:54
In this program every QquickItem has friends. And i need to get this friend. But i can't call function which get friends every time when i need it so it is comfortable when you can customise this class

wysota
3rd April 2013, 19:58
In this program every QquickItem has friends.
What friends?


But i can't call function which get friends every time when i need it so it is comfortable when you can customise this class
I'm sorry, I don't understand you. I'm afraid I can't help.

Ichi
3rd April 2013, 20:11
ok i think it doesn't matter what friend or whatever.
i simply wanted customise this class because in some cases it is much comfortable, i wanted add 2 or 3 methods this is all.

d_stranz
4th April 2013, 02:19
i simply wanted customise this class because in some cases it is much comfortable, i wanted add 2 or 3 methods this is all.

You can always derive a custom class from QQuickItem and add more methods to it.

However the QQuickItem::childItems() will always return QList< QQuickItem * >. You need to do something like this:



QList< QQuickItem * > children = root->childItems();

QListIterator< QQuickItem * > it( children );
while ( it.hasNext() )
{
QQuickItem * pItem = it.next();
MyItem * pMyItem = qobject_cast< MyItem * >( pItem );
if ( pMyItem ) // check for NULL - if it is null, then the item was not a MyItem
{
pMyItem->callMyMethod();
}
}

wysota
4th April 2013, 07:56
qobject_cast will definitely fail here. He doesn't want to insert new items in the scene that are to be MyItem instances, he wants all items in the scene to magically be MyItem instances (because items in his scene have "friends") thus any cast other than a crude static_cast will fail. I don't understand the point of all this discussion, it seems to me OP just wants to do myItem->callMyMethod() instead of callMyMethod(myItem).

anda_skoa
4th April 2013, 10:15
Well, it is really unclear.

If the OP has a QtQuick item class and only creates those or subclasses of it, then the approach by d_stranz will of course work.

Ichi, can you provide a QML snippet showing your use of QtQuick?

Cjeers,
_

d_stranz
4th April 2013, 20:53
If the OP has a QtQuick item class and only creates those or subclasses of it, then the approach by d_stranz will of course work.

That's what I understood he was trying to say here:


ok i want use my own instance of QQuickItem in QQuickView. For example:
I make my class MyItem - public class Item : public QQuickItem
QQuickView *view = new QQuickView();
view->rootObject->itemsChild(); and i want that this will return QList<MyItem> items;

wysota
4th April 2013, 21:12
I don't see him create any instances of MyItem in here. And he also said he wants all items to be MyItem instances. I assumed there is no QtQuick program that can work without even a single instance of any predefined elements.

anda_skoa
5th April 2013, 14:01
I don't see him create any instances of MyItem in here.

I assumed that the whole scene is created in QtQuick. For QtQuick2 (which we have here judging by class name) this is basically the only sensible way.
Hence my request to see the QML part



And he also said he wants all items to be MyItem instances. I assumed there is no QtQuick program that can work without even a single instance of any predefined elements.

I don't see why it would not, i.e. I am not aware of any requirement to have a certain type for top level element, I assume it can be any QQuickItem subclass.

Cheers,
_

Ichi
5th April 2013, 14:18
simply forgot all what i said i want customise QQuickItem (add 2 methods). And use this for all items in QQuickView.

d_stranz
5th April 2013, 23:24
OK, then you will want to use something like the code I posted:



QList< QQuickItem * > children = root->childItems();

QListIterator< QQuickItem * > it( children );
while ( it.hasNext() )
{
QQuickItem * pItem = it.next();
MyItem * pMyItem = qobject_cast< MyItem * >( pItem );
if ( pMyItem ) // check for NULL - if it is null, then the item was not a MyItem
{
pMyItem->callMyMethod();
}
}

wysota
5th April 2013, 23:50
I'm still not convinced that's the case. It would seem logical that if a person knows how to create a QtQuick scene using only custom qml elements that first need to be written and then registered and he has no problems with that (we haven't seen his question about it here on the forum) he would also know to use qobject_cast to cast from QQuickItem to his own class. Therefore I think we're dealing with much simpler situation. I think OP has code similar to this one:

Item {
property sometype somename; // "friend of Item?"
// ...
}

that defines "friends" (whatever that is) for items in the scene and he wants to launch some C++ code on those "friends" hoping to make that code a method of the item class. That's why I asked what "friends" we were dealing with but unfortunately OP didn't find it important for the problem.

The real problem is the language barrier -- OP simply can't clearly state what is his problem and we're just guessing what it might be.

If I'm right about OP's intentions then I suggest to put that added code into standalone functions or into methods of some external class and execute those methods for each item passing the item as the argument of the method. If I'm wrong, then of course qobject_cast might be the proper answer to the original problem.

Ichi
6th April 2013, 12:10
qobject_cast is right but this time it works but what when i will have in root object 1000 children and every children will have next 1000 children (this is only example)
Yes i allways can do it whit qobject_cast but i think this is not quite "kosher" ok it is solved

wysota
6th April 2013, 17:08
What are you doing with a scene that has one million items?

d_stranz
6th April 2013, 18:36
qobject_cast is right but this time it works but what when i will have in root object 1000 children and every children will have next 1000 children (this is only example)
Yes i allways can do it whit qobject_cast but i think this is not quite "kosher" ok it is solved

If you know that every item in your scene is a "MyItem" derived from QQuickItem, then simply keep a separate list of every MyItem * instead of asking QQuickView for the root's childItems. Then there is no need for qobject_cast<>. The code I posted is for when you have a mixed list of items - some are MyItem, some are not.

qobject_cast<> is always kosher when you need to extract a subset of items from a list of pointers to base classes. But if you have many items and you will be doing this many times, then it is more efficient (in speed) to keep a separate list of the things you are interested in. It takes more memory, but it is faster at run time.

@Wysota:

that defines "friends" (whatever that is)

It's a Japanese - English translation issue, not a C++ issue. He simply means two classes that know something about each other. He wants to make MyItem instances that extend QQuickItem with new methods that can be retrieved and used by instances of other classes that know about the additional methods. For convenience, he wanted these returned as a QList< MyItem * >.

I'd have an equally difficult time expressing that same concept in Japanese.

wysota
6th April 2013, 22:35
@Wysota:


It's a Japanese - English translation issue, not a C++ issue. He simply means two classes that know something about each other. He wants to make MyItem instances that extend QQuickItem with new methods that can be retrieved and used by instances of other classes that know about the additional methods. For convenience, he wanted these returned as a QList< MyItem * >.

I'd have an equally difficult time expressing that same concept in Japanese.

To be honest I can't understand your English explanation :)

anda_skoa
7th April 2013, 12:16
If you know that every item in your scene is a "MyItem" derived from QQuickItem, then simply keep a separate list of every MyItem * instead of asking QQuickView for the root's childItems.


That wouldn't actually be that difficult. Basically only requires a static container member in MyItem and register/unregister in constructor and destructor. something like this



class MyItem : public QQuickItem
{
Q_OBJECT

public:
explicit MyItem( QQuickItem *parent = 0 ) : QQuickItem( parent )
{
s_items.insert( this );
}

~MyItem()
{
s_item.remove( this );
}

static QSet<MyItem*> allMyItems() { return s_items; }

private:
static QSet<MyItem*> s_items;
}


And then be used like this



Q_FOREACH ( MyItem *item, MyItem::allMyItems() ) {
// do something with item
}


Cheers
_