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. QVariantMap/QObject store bag
Forum Updated to NodeBB v4.3 + New Features

QVariantMap/QObject store bag

Scheduled Pinned Locked Moved General and Desktop
16 Posts 3 Posters 10.3k Views 1 Watching
  • 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.
  • G Offline
    G Offline
    Gourmand
    wrote on last edited by
    #1

    To store settings of application with multithreaded plugins I want create a class something like this:

    @class VariantSettings : QVariantMap, QObject
    {
    public slots:
    void storeVariant( QString name, QVariant value );
    void retrieveVariant( QString name );
    signals:
    void valueVariant( QVariant value );
    }@

    Slots and signals have to be connected via Qt::AutoConnection to safely deliver values if sender and receiver are in different threads. Received in storeVariant() value it just stores in it's QMap. If it receives request in retrieveVariant() then it sends signal valueVariant() with stored value. Probably all must work fine but I just want ask somebody who did same before - can I wait something unexpected. Are there any "underwater rocks" in this design?

    I just did not ever used QMap before and as I see it is not a QObject. May be there is some reason to not make such a solution, is there?

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

      Why do you want to inherit from QVariantMap? Your class could simply encapsulate one instead. That would get rid of the multiple inheritance and hide what is basically an implementation detail anyway. And, you need to inherit publicly from QObject of course.

      Apart from that, sure, it could work I think. Not sure if the design is all that pretty, but then again, I don't know your requirements.

      1 Reply Last reply
      0
      • G Offline
        G Offline
        Gourmand
        wrote on last edited by
        #3

        bq. Why do you want to inherit from QVariantMap?

        QMap is a superclass, therefore I don't see where from "rhombus" inheritance can appear.

        1 Reply Last reply
        0
        • G Offline
          G Offline
          Gourmand
          wrote on last edited by
          #4

          Not clearly relative to this topic question: Can QVariantMap entirely be sent through slot connection? I do not want send pointer to it (because of threading). And do not want send it's content "line by line".

          1 Reply Last reply
          0
          • L Offline
            L Offline
            lgeyer
            wrote on last edited by
            #5

            I wouldn't inherit from QVariantMap either; just encapsulate one - as Andre said.
            It's not about beeing not possible it's about good class design.

            Just be sure to properly guard your accesses with mutexes or read/write locks as containers are reentrant but not threadsafe.

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

              [quote author="Gourmand" date="1311928472"]bq. Why do you want to inherit from QVariantMap?

              QMap is a superclass, therefore I don't see where from "rhombus" inheritance can appear.
              [/quote]
              I did not say that such an inheritance structure does appear, I just asked why you think your class should inherit from QVariantMap. Because based on what you told us in your opening post, it doesn't seem to be needed, and can potentially be dangerous due to the fact that QVariantMap does not have a virtual destructor.

              [quote author="Gourmand" date="1311928938"]Not clearly relative to this topic question: Can QVariantMap entirely be sent through slot connection? I do not want send pointer to it (because of threading). And do not want send it's content "line by line".[/quote]
              Yes, that is possible. Possibly not cheap, but possible. But why would you want to do that? You were just showing us methods to access individual data points, and I thought the whole point was to do that thread save.

              1 Reply Last reply
              0
              • G Offline
                G Offline
                Gourmand
                wrote on last edited by
                #7

                bq. I just asked why you think your class should inherit from QVariantMap.

                Ok, this allows access to settings inside plugin just like this:

                @VariantSettings settings;
                ...
                int somenumber = settings[ "somenumber" ];
                QString somestring = settings[ "somestring" ];@
                ... so on

                But in main application settings are accessed using signals/slot. Reason is: main application stores and edits settings for all plugins (it automatically creates settings dialogs for all loaded plugins), but plugins use those settings.

                bq. But why would you want to do that?

                I just told that this is Not clearly relative to this topic question

                1 Reply Last reply
                0
                • G Offline
                  G Offline
                  Gourmand
                  wrote on last edited by
                  #8

                  bq. can potentially be dangerous due to the fact that QVariantMap does not have a virtual destructor

                  I see it is declared like this:

                  @typedef QMap<QString, QVariant> QVariantMap;@

                  exactly it is a QMap which has virtual destructor.

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

                    [quote author="Gourmand" date="1311933819"][quote] can potentially be dangerous due to the fact that QVariantMap does not have a virtual destructor[/quote]

                    I see it is declared like this:

                    @typedef QMap<QString, QVariant> QVariantMap;@

                    exactly it is a QMap which has virtual destructor.[/quote]

                    Really? Is QMap's destructor virtual? In the source code I have here, it looks like this:

                    @
                    template <class Key, class T>
                    class QMap
                    {
                    typedef QMapNode<Key, T> Node;
                    typedef QMapPayloadNode<Key, T> PayloadNode;

                    // (...)
                    public:
                    inline QMap() : d(&QMapData;::shared_null) { d->ref.ref(); }
                    inline QMap(const QMap<Key, T> &other;) : d(other.d)
                    { d->ref.ref(); if (!d->sharable) detach(); }
                    inline ~QMap() { if (!d) return; if (!d->ref.deref()) freeData(d); }
                    //(...)
                    }
                    @

                    Doesn't look all that virtual to me...

                    [quote author="Gourmand" date="1311933502"][quote] I just asked why you think your class should inherit from QVariantMap.[/quote]

                    Ok, this allows access to settings inside plugin just like this:

                    @VariantSettings settings;
                    ...
                    int somenumber = settings[ "somenumber" ];
                    QString somestring = settings[ "somestring" ];@
                    ... so on

                    But in main application settings are accessed using signals/slot. Reason is: main application stores and edits settings for all plugins (it automatically creates settings dialogs for all loaded plugins), but plugins use those settings.[/quote]
                    So, if I understand you correctly, it is just because in your class implementation, you don't want to type things like this:
                    @VariantSettings settings;
                    ...
                    int somenumber = m_valueMap.settings[ "somenumber" ];
                    QString somestring = m_valueMap.settings[ "somestring" ];
                    @

                    OK, I guess that could be an argument, but IMHO, not a good one.

                    [quote][quote]But why would you want to do that?[/quote]
                    I just told that this is Not clearly relative to this topic question
                    [/quote]
                    OK, so I misunderstood. It is probably wise though not to confuse a topic with irrelevant side-questions if you want a clear answer.

                    1 Reply Last reply
                    0
                    • L Offline
                      L Offline
                      lgeyer
                      wrote on last edited by
                      #10

                      [quote author="Gourmand" date="1311933502"]
                      Ok, this allows access to settings inside plugin just like this:

                      @
                      VariantSettings settings;
                      ...
                      int somenumber = settings[ "somenumber" ];
                      QString somestring = settings[ "somestring" ];@
                      [/quote]

                      QMap and so QVariantMap is reentrant, not threadsafe. If you expose any of the QMap interface your resulting class will also be reentrant, not threadsafe.

                      If you like to provide such functionality you will have to provide your own thread-safe index operator.

                      1 Reply Last reply
                      0
                      • G Offline
                        G Offline
                        Gourmand
                        wrote on last edited by
                        #11

                        @QMap and so QVariantMap is reentrant, not threadsafe. If you expose any of the QMap interface your resulting class will also be reentrant, not threadsafe.

                        If you like to provide such functionality you will have to provide your own thread-safe index operator.@

                        I will use QMutex protection of course.

                        @you don’t want to type things like this:

                        VariantSettings settings;
                        ...
                        int somenumber = m_valueMap.settings[ "somenumber" ];
                        QString somestring = m_valueMap.settings[ "somestring" ];
                        @

                        this should be

                        @int somenumber = settings.m_valueMap[ "somenumber" ];
                        QString somestring = settings.m_valueMap[ "somestring" ];@

                        indeed.

                        Yes I don't want. And this is for plugins which can be developed by other people, not only me. I want remove any extra essence if it is not necessary.

                        @Doesn’t look all that virtual to me…@

                        Hm, exactly... But does this really matter in my case?

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

                          [quote author="Gourmand" date="1311938674"][quote]Doesn’t look all that virtual to me…[/quote]

                          Hm, exactly... But does this really matter in my case?
                          [/quote]
                          Yes. A plugin could do this:

                          @
                          QVariantMap* theValues = new VariantSettings(this);
                          // ...
                          delete theValues; //undefined behaviour!
                          @

                          [quote author="Gourmand" date="1311938674"]
                          [quote]you don’t want to type things like this:
                          @
                          VariantSettings settings;
                          ...
                          int somenumber = m_valueMap.settings[ "somenumber" ];
                          QString somestring = m_valueMap.settings[ "somestring" ];
                          @
                          [/quote]

                          this should be

                          @
                          int somenumber = settings.m_valueMap[ "somenumber" ];
                          QString somestring = settings.m_valueMap[ "somestring" ];
                          @

                          indeed.

                          Yes I don't want. And this is for plugins which can be developed by other people, not only me. I want remove any extra essence if it is not necessary.
                          [/quote]
                          I guess I misunderstood where those lines would occur. I interpretted them as being inside of the VariantSettings class itself. Obviously you would not do what you show in your second example; that would be just as bad or worse as multiple inheritance and at the very least very ugly.

                          What I would do is hide the actual storage mechanism. Instead, you provide your own API that you make save for use across threads. It could follow the API that is there for QMap if you like. Note that you can not override the methods of QMap anyway, as none of them are virtual.

                          Finally: please don't use code tags where you are quoting others. It is confusing, leads to ugly-formatted posts and makes replying harder. Quotes can be nested, though the bq. doesn' t work that way (forum bug).

                          1 Reply Last reply
                          0
                          • L Offline
                            L Offline
                            lgeyer
                            wrote on last edited by
                            #13

                            [quote author="Gourmand" date="1311938674"]Hm, exactly... But does this really matter in my case?[/quote]

                            Not as long as you are aware that your destructor won't be called if the object is deleted through a base class pointer.

                            However, you create code that is broken by design, and "anything that can go wrong will go wrong".

                            1 Reply Last reply
                            0
                            • G Offline
                              G Offline
                              Gourmand
                              wrote on last edited by
                              #14

                              bq. Yes. A plugin could do this:

                              @QVariantMap* theValues = new VariantSettings(this);
                              // ...
                              delete theValues; //undefined behaviour!@

                              No, it could not. The VariantSettings object is a property of plugin class. Accessed not by pointer but as field of plugin class. The plugin inherits "plugin interface" of course. Even settings object can be a property of interface class. No other settings object will be defined for plugin ever. One plugin - one VariantSettings object. It will be destroyed with plugin object. No virtual destructor needed.

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

                                Fine. If you are so certain about your design, then why come here and ask for advice on it in the first place? It is hard to give you good advice based on the bits and pieces of information that you are actually providing, and at least for me, my mental image of what you are trying to achieve has shifted with each of your posts.

                                So: have fun. Go ahead and implement it all in the way you outlined here. I hope it proves to be smooth sailing for you.

                                1 Reply Last reply
                                0
                                • G Offline
                                  G Offline
                                  Gourmand
                                  wrote on last edited by
                                  #16

                                  bq. If you are so certain about your design, then why come here and ask for advice on it in the first place?

                                  Because I need to somebody help me find possible troubles which I cannot see. I told - I did not use QMap before.

                                  Thanx for advices. All was helpful.

                                  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