Important: Please read the Qt Code of Conduct -

[SOLVED] QObject with QHash instead of QList for children

  • Hi !
    I would like to use both the QObject class facilities and a QHash for its children. Is there a simple way to do this ?

  • You can listen to "QObject::childEvent() ": and populate your hash yourself.

    Another approach could be to give the objects proper names (see the "objectName property":, be aware that the names must be unique then) and use "QObject::findChildren() ": to search the object in question.

  • Thank you for answering so quick.

    I hesitate between not to use an hash table at all(and loose some efficiency) or not to use the QList, add a QHash in my class and reimplement all those findChild(), removeChild(), etc, functions, and not to use an QObject at all for this...

    The context is :
    I learn OpenGL and how to build a graphic rendering engine. I use a tree structure for my 3d objects and though that inheriting my Node class from QObject could save me some time and permit me to use some special features (QPointer, and such) only available to QObjects.

  • A hash presupposes a key. I am wondering what you plan to use as a key?

    How many children per object are you looking at?

  • A simple way could be to create a class like this :
    @class CMyHash : public QObject, public QHash@

    and then using this class on your parent QObject.

  • Andre : I haven't read throught all te doc about QHash, last time I used hash tables it was in pure C with dynamic arrays, coded by hand ;). I cannot fix a number of children, it may be 1 or 2 384 392. If the user draws a tree, there are many leafs to that tree. The important thins is that there will be much more queries to access the content than add/remove operation (which are not very efficient with hash tables). I think the key would be a name, stocked in a string, or something build around the position of the node. The only thing important is that the key should be unique, or I should use a QMultiHash.

    ngrosjean The class I create (Node) is not a hash table but contains one. There is a typedef in QObject class : QObjectList which is equivalent to QList<QObject * > . This is what I want to replace with QHash<key, Node * >. So I would not use the type you gave, if only for logical reasons. If I remember well my OO courses, A inherits B implies B is a A ;-),

    Or I could reimplement findChild(), findChildren(), etc so the QObjectList behave like a hash table.

  • The point of having a hash, is that you can quickly look up an item using a key. From your description, it seems that that is not your primary goal. Why do you think you need to replace the default list implementation with a hash? What do you want to achieve with that? What kind of queries do you need to be able to facilitate?

    I doubt you'll be able to make the actual replacement happen by the way. You could strap a hash of the children on top of the default implementation in a QObject subclass, but completely replacing it is impossible without patching Qt itself, I think.

    ngrosjean: it is not a good idea to inherit from classes that have a non-virtual destructor such as Qt's collection classes.

  • I need to look up specific item in a certain order 30 - 60 times per second to render them. The Node contains orientation information (Quaternion), position information (Vector), scale information (Vector) and a container of ressources (Textures, material, and so on). All those informations must be fed to OpenGL to update the scene when in realtime rendering or in a video game context. But I don't want to access all information at each render phase is there were no change (I don't want to simply iterate on a list).

    The same Node class will be used in case of animation rig (bones of an animated character, by example). In fact, this is an abstract class.

    But you are right in the sense that it would cost me hours or reimplementation to use a hash table for maybe not much efficiency gain. Some graphic rendering implementations use hash tables in this context (OGRE, just to name one).

    I have to decide between

    • inheriting Node from QObject and don't use a Qhash, or
    • Not inheriting Node from QObject and use a Qhash (or any other custom hash table, which I may have already in some old code archives ;) )

    If you have some suggestion, I'll be glad to hear it. I let this thread open until I make my mind and will describe in more details what I have done in case it could help someone someday

  • Why do you want to inherit from QObject? From what I've understand you do not need its additional functionality. You did mention neither signals/slots nor properties, which would be the most wanted features.

    From this perspective I would suggest a simple class with a QHash as member for the children.

    PS: You can not change QList to QHash in the QObject without investing weeks of work to patch Qt.

  • I wanted to use special pointers available only for QObject instances, to create signals (which I can otherwise implement in my custom QGLWidget like "Object3DHovered") and maybe some slots (which can also be handled by the custom QGLWidget).

    I think it could be a good improvement to choose the container used to store a QObject children. Maybe in Qt5 ? ;)

    So, to my original question
    [quote author="Maneithel" date="1299531482"]Hi !
    I would like to use both the QObject class facilities and a QHash for its children. Is there a simple way to do this ?[/quote]
    the answer is "no". I must target the key features I need in QObject and see i f I can implement them by myself or make them be handled by an other class (responsability transfer).

    Thanks a lot for your help !

Log in to reply