Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Problem, How do I return my own QObject derived custom class as "QVariant"?

    General and Desktop
    4
    12
    9289
    Loading More Posts
    • 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.
    • R
      ronM71 last edited by

      Implementing a derived "QAbstractListModel::data" method.

      Q_DECLARE_METATYPE(myType); doesn't even compile.... returning my custom object results in a compilation error.

      How can this be done?

      1 Reply Last reply Reply Quote 0
      • G
        goetz last edited by

        Some code?

        http://www.catb.org/~esr/faqs/smart-questions.html

        1 Reply Last reply Reply Quote 0
        • R
          ronM71 last edited by

          Ok. hint well taken.

          This is a class I got. Fairly simple. I want to have a QListView that'll connect to a model that owns a list of such instances. The reason is I need to manipulate the drawing (complex w/ added buttons per row) as well as sorting.

          When i implement ::data on my derived QAbstractListModel i am trying to return one of these objects (which i store on a std::vector). I get a compilation error as its wants a QVariant and it's not compatible with my class. I tried adding Q_DECLARE_METATYPE(Contact); after my class declaration but it gives me a compilation error (../source/Contact.h:42: error: expected constructor, destructor, or type conversion before ';' token)

          [i do implement the constructor, copy constructor and assignment operator in the cpp file. no worries]
          @
          #include <QtGlobal>
          #include <QObject>

          typedef enum ContactOnlineStatus_
          {
          OFFLINE = 0,
          ONLINE = 1,
          BUSY = 2
          } ContactOnlineStatus;

          class Contact : public QObject
          {
          Q_OBJECT

          public:
          explicit Contact(QObject *parent = 0);
          Contact (const Contact & rhs);
          Contact & operator=(const Contact & rhs);

          // setters
          
          void SetName(QString name) { this->name = name;}
          void SetOnlineStatus(ContactOnlineStatus status) {this->onlineStatus = status;}
          void SetInBuddyList(bool inBuddyList) {this->inBuddyList = inBuddyList;}
          
          // getters
          
          QString GetName() {return name;}
          ContactOnlineStatus GetOnlineStatus() {return onlineStatus;}
          bool GetInBuddyList() {return inBuddyList;}
          

          private:
          QString name;
          ContactOnlineStatus onlineStatus;
          bool inBuddyList;

          };@

          The model....
          @
          class ContactsModel : public QAbstractListModel
          {
          Q_OBJECT
          public:
          explicit ContactsModel(QObject *parent = 0);

          virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
          virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
          

          signals:

          public slots:

          private:
          std::vector<Contact> contacts;
          };
          @

          The ::Data implementation...

          @QVariant ContactsModel::data(const QModelIndex &index, int role) const
          {
          if (!index.isValid())
          return QVariant();

          if (index.row() >= this->contacts.size())
          

          return QVariant();

          if (role == Qt::DisplayRole)
          {
          

          return qVariantFromValue(this->contacts[index.row()]); <-- this is one of the things I tried. nothing worked.....
          }
          else
          return QVariant();
          }@

          1 Reply Last reply Reply Quote 0
          • R
            ronM71 last edited by

            One correction.

            Changed:

            @return qVariantFromValue(this->contacts[index.row()]);@

            To:

            @return qVariantFromValue(&this->contacts[index.row()]);@

            as it needs a pointer.. but now I am getting a build error:

            /Library/Frameworks/QtCore.framework/Headers/qmetatype.h:222: error: 'qt_metatype_id' is not a member of 'QMetaTypeId<const Contact*>'

            It's obvious I am missing a declaration to "validate" the class I am using. What it is escapes me.

            1 Reply Last reply Reply Quote 0
            • R
              ronM71 last edited by

              "Q_DECLARE_METATYPE" is simply unknown. do I need to include an *.h file for it? my compiler simply doesn't know about this. This is really weird.

              1 Reply Last reply Reply Quote 0
              • Z
                ZapB last edited by

                You need:

                @#include <QMetaType>@

                Nokia Certified Qt Specialist
                Interested in hearing about Qt related work

                1 Reply Last reply Reply Quote 0
                • R
                  ronM71 last edited by

                  Yep. i got it compiling now. thanks.

                  1 Reply Last reply Reply Quote 0
                  • Z
                    ZapB last edited by

                    Good stuff. If you ever need to pass your custom types as arguments in signals across thread boundaries remember that you will also need to call qRegisterMetaType() too.

                    Nokia Certified Qt Specialist
                    Interested in hearing about Qt related work

                    1 Reply Last reply Reply Quote 0
                    • R
                      ronM71 last edited by

                      At what point do you call QRegisterMetaType()? application object? after main?

                      1 Reply Last reply Reply Quote 0
                      • Z
                        ZapB last edited by

                        It's all in the "docs":http://doc.qt.nokia.com/latest/qmetatype.html#qRegisterMetaType. You call it before you use it in a signal/slot connection. This is only needed if you need to pass your type as an argument in a queued connection. If all your connections are within the sam thread then you do not need to worry about it.

                        If you do need it then just call it once for your type before you use it in a connection.

                        Nokia Certified Qt Specialist
                        Interested in hearing about Qt related work

                        1 Reply Last reply Reply Quote 0
                        • A
                          andre last edited by

                          Looks like your std::vector (why not use QVector or QList?) contains actual instances of your Contact class. Because Contact inherits QObject, and QObject is not mend to be copied around, you should store pointers in your vector instead.

                          1 Reply Last reply Reply Quote 0
                          • Z
                            ZapB last edited by

                            Agreed. The compiler should complain about a lack of a public QObject copy constructor (assuming that you call the base class copy ctor in your overridden one). Never try to copy QObject's around. What happens to the parent for example ie who owns the new object?

                            Nokia Certified Qt Specialist
                            Interested in hearing about Qt related work

                            1 Reply Last reply Reply Quote 0
                            • First post
                              Last post