I need to add my own objects to QComboBox
instead of just QStrings
. Here's my own class, I need to add its objects to combo box:
#ifndef SERVICE_H
#define SERVICE_H
#include <QString>
#include <QMetaType>
#include <QVariant>
#include <QObject>
class Service : public QObject
{
Q_OBJECT
public:
Service(QString name, double price);
Service(){ name = ""; price = 0;}
QString getServiceName() const;
void setServiceName(const QString &value);
double getServicePrice() const;
void setServicePrice(double value);
private:
QString name;
double price;
};
Q_DECLARE_METATYPE(Service)
#endif // SERVICE_H
#include "service.h"
Service::Service(QString name, double price)
{
this->name = name;
this->price = price;
}
QString Service::getServiceName() const
{
return name;
}
void Service::setServiceName(const QString &value)
{
name = value;
}
double Service::getServicePrice() const
{
return price;
}
void Service::setServicePrice(double value)
{
price = value;
}
And here's the piece of code, which sets up the combo box:
QVector<Service> services;
services.push_back(Service("Service 1", 100));
services.push_back(Service("Service 2", 150));
servicesComboBox = new QComboBox;
servicesComboBox->addItem("Service 1", QVariant::fromValue(services[0]));
servicesComboBox->addItem("Service 2", QVariant::fromValue(services[1]));
QObject::connect(servicesComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(chooseService(int)));
Then, I have a slot, in which I would like to get the selected object, and let's say, save in database:
void ClientTab::chooseService(int index)
{
QVariant v = servicesComboBox->itemData(index);
Service *s = v.value<Service *>();
}
And the errors:
g++ -c -pipe -O2 -Wall -W -D_REENTRANT -fPIC -DQT_NO_DEBUG
-DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_SQL_LIB -DQT_CORE_LIB -I../TestApp -I. -I/opt/Qt/5.5/gcc_64/include -I/opt/Qt/5.5/gcc_64/include/QtWidgets -I/opt/Qt/5.5/gcc_64/include/QtGui -I/opt/Qt/5.5/gcc_64/include/QtSql -I/opt/Qt/5.5/gcc_64/include/QtCore -I. -I. -I/opt/Qt/5.5/gcc_64/mkspecs/linux-g++ -o clienttab.o ../TestApp/clienttab.cpp ../TestApp/clienttab.cpp: In member function 'void ClientTab::chooseService(int)': ../TestApp/clienttab.cpp:48:14: warning: unused variable 's' [-Wunused-variable]
Service *s = v.value<Service *>();
^ In file included from /opt/Qt/5.5/gcc_64/include/QtGui/qwindowdefs.h:37:0,
from /opt/Qt/5.5/gcc_64/include/QtWidgets/qwidget.h:37,
from /opt/Qt/5.5/gcc_64/include/QtWidgets/QWidget:1,
from ../TestApp/clienttab.h:4,
from ../TestApp/clienttab.cpp:1: ../TestApp/service.h: In instantiation of 'void QVector<T>::append(const T&) [with T = Service]': /opt/Qt/5.5/gcc_64/include/QtCore/qvector.h:225:49: required from 'void QVector<T>::push_back(const T&) [with T = Service]' ../TestApp/clienttab.cpp:22:65: required from here /opt/Qt/5.5/gcc_64/include/QtCore/qobject.h:461:20: error: 'QObject::QObject(const QObject&)' is private
Q_DISABLE_COPY(QObject)
^ /opt/Qt/5.5/gcc_64/include/QtCore/qglobal.h:1042:5: note: in definition of macro 'Q_DISABLE_COPY'
Class(const Class &) Q_DECL_EQ_DELETE;\
^ In file included from ../TestApp/clienttab.cpp:2:0: ../TestApp/service.h:9:7: error: within this context class Service : public QObject
^ In file included from /opt/Qt/5.5/gcc_64/include/QtGui/qbrush.h:39:0,
from /opt/Qt/5.5/gcc_64/include/QtGui/qpalette.h:39,
from /opt/Qt/5.5/gcc_64/include/QtWidgets/qwidget.h:41,
from /opt/Qt/5.5/gcc_64/include/QtWidgets/QWidget:1,
from ../TestApp/clienttab.h:4,
from ../TestApp/clienttab.cpp:1: /opt/Qt/5.5/gcc_64/include/QtCore/qvector.h:605:23: note: synthesized method 'Service::Service(const Service&)' first required here
const T copy(t);
^ In file included from /opt/Qt/5.5/gcc_64/include/QtGui/qwindowdefs.h:37:0,
from /opt/Qt/5.5/gcc_64/include/QtWidgets/qwidget.h:37,
from /opt/Qt/5.5/gcc_64/include/QtWidgets/QWidget:1,
from ../TestApp/clienttab.h:4,
from ../TestApp/clienttab.cpp:1: /opt/Qt/5.5/gcc_64/include/QtCore/qglobal.h:1043:12: error: 'QObject& QObject::operator=(const QObject&)' is private
Class &operator=(const Class &) Q_DECL_EQ_DELETE;
^ /opt/Qt/5.5/gcc_64/include/QtCore/qobject.h:461:5: note: in expansion of macro 'Q_DISABLE_COPY'
Q_DISABLE_COPY(QObject)
^ In file included from ../TestApp/clienttab.cpp:2:0: ../TestApp/service.h:9:7: error: within this context class Service : public QObject
^ In file included from /opt/Qt/5.5/gcc_64/include/QtGui/qbrush.h:39:0,
from /opt/Qt/5.5/gcc_64/include/QtGui/qpalette.h:39,
from /opt/Qt/5.5/gcc_64/include/QtWidgets/qwidget.h:41,
from /opt/Qt/5.5/gcc_64/include/QtWidgets/QWidget:1,
from ../TestApp/clienttab.h:4,
from ../TestApp/clienttab.cpp:1: /opt/Qt/5.5/gcc_64/include/QtCore/qvector.h:612:23: note: synthesized method 'Service& Service::operator=(const Service&)' first required here
*d->end() = copy;
^ make: *** [clienttab.o] Error 1
I'm using Qt 5.5 on Kubuntu 14.04 LTS.
You are storing the items by value, but in the slot you are retrieving pointers to them. That's why it crashes. Also the Service
class does not have a copy constructor (so I'm not sure why the Q_DECLARE_METATYPE
even compiles). Copy constructor of QObject
is private, so the default copy constructor for Service
will not be generated by the compiler.
Changing initialisation code like this should work:
QVector<Service*> services;
services.push_back(new Service("Service 1", 100));
services.push_back(new Service("Service 2", 150));
Side note: you will also have to take care of deleting the instances of Service
when you no longer need them. Since Serive
derives from QObject
, consider doing it via the parent-child relationship.
EDIT Also change the meta type declaration to use the pointer:
Q_DECLARE_METATYPE(Service*)