Problem, How do I return my own QObject derived custom class as "QVariant"?
-
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_OBJECTpublic:
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();
}@ -
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.
-
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.
-
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?