Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. [Solved] Reading Key/Values from QHash
QtWS25 Last Chance

[Solved] Reading Key/Values from QHash

Scheduled Pinned Locked Moved General and Desktop
6 Posts 3 Posters 9.9k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    Sam
    wrote on last edited by
    #1

    I have a hash table that stores a QString (Key) and QObject(value) .

    @QHash<QString,QObject *> hashTable;@

    here i can insert the values as

    @hashTable.insert("A",new QLabel("A"));
    hashTable.insert("C",new QLabel("C"));
    hashTable.insert("D",new QLabel("D"));
    hashTable.insert("F",new QLabel("F"));
    hashTable.insert("B",new QLabel("B"));
    hashTable.insert("G",new QLabel("G"));
    hashTable.insert("E",new QLabel("E"));@

    But while reading the keys from the hashTable using

    @foreach (QString string, hashTable.keys()) {

        qDebug()<<string;
    }@
    

    or

    @QHashIterator<QString, QObject*> i(hashTable);
    while(i.hasNext()) {
    i.next();
    qDebug()<<i.key();
    }@

    I get the output as

    @"D"
    "E"
    "F"
    "G"
    "A"
    "B"
    "C"@

    Which is not the order in which the keys were inserted to the hashTable.
    Is there any way to read the keys in the same way it is inserted?

    1 Reply Last reply
    0
    • A Offline
      A Offline
      andre
      wrote on last edited by
      #2

      A QHash does not keep the items in the order you inserted them. If you need that, use [[doc:QMap]] instead. If the order does not matter, prefer QHash as performs a bit better.

      1 Reply Last reply
      0
      • S Offline
        S Offline
        Sam
        wrote on last edited by
        #3

        @Andre

        From the documentation of QHash , i got

        bq. QHash is unordered, so an iterator's sequence cannot be assumed to be predictable. If ordering by key is required, use a QMap.

        But in QMap it sorts the list based on the key, so output comes out to be

        @"A"
        "B"
        "C"
        "D"
        "E"
        "F"
        "G"@

        Which is not the order in which the key/values were inserted.

        Another approach i thought of is using a
        @QList</Structure (Struct)/>@

        where the Structure stores values as

        @struct ObjectList{
        QString name;
        QObject *object;
        };@

        or

        @QList<QPair<QString,QObject*> > // don't know if this will work n i don't prefer much to use it either@

        Which one should i use / any other approach to get the same.
        Thanks for the help :)

        1 Reply Last reply
        0
        • D Offline
          D Offline
          DerManu
          wrote on last edited by
          #4

          You could also just save the QObject in a QList<QObject*> and use objectName/setObjectName for the key. So when you search for an object, either use the built-in findChild of the objects parent or go through the list yourself and check the objectName properties.

          Otherwise I agree with your two methods, but would still turn the struct into a small class with Constructor that takes initialization values for the members.

          If you want fast access and keep the order (i.e. have > 10000 objects and access them by key regularly), combine a QHash (for fast access by key) with a QList<QString> (for storing the keys in an ordered fashion).

          1 Reply Last reply
          0
          • A Offline
            A Offline
            andre
            wrote on last edited by
            #5

            Ah, right, yes. A map is ordered by key, not by insertion. In your example it would have have mattered due to the two being the same, but you are right. Your idea of using a struct is good, if you cannot store the object name inline with the object. Personally, I prefer it over using QPair, because it results in more readable code. The QPair::first and QPair::second names are not all that informative about what actually is first and what is second. It will work though, you only need to add a space between the two >>'s (otherwise it is interpretted as a streaming operator). Typedefs would make the construct more readable, but still not great.

            So yes, creating a
            @
            struct ObjectNode
            {
            QString name;
            QObject* object;
            }

            typedef QList<ObjectNode> ObjectList;
            @
            is not a bad idea. If you still need lookups by name, you can then just add a
            @
            QHash<QString, int>
            @
            to keep track of the indexes in your list (or QVector, if you could use that instead of QList) for each name. If you insert a copy of the string, that doesn't waste too much space.

            1 Reply Last reply
            0
            • S Offline
              S Offline
              Sam
              wrote on last edited by
              #6

              For now I'll stick to -creating a struct and storing it in a QList. As here the requirement is to load a frame/form whose values and specifications are provided in a xml file. So i need a container that contains both the key(name) and value(object).

              Thanks for your time :)
              This is solved.

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved