In class called UserForms, I define a list (QList) or SqlQueryModel objects (subclass of QSqlQueryModel), as in this Qt tutorial.
In userforms.h:
QList<SqlQueryModel> userModels;
Then in my main code, I want to iterate over userModel, so I tried both of the following:
UserForm selectedUF = formSelectorDiag.getSelectedUF();
QList<SqlQueryModel>::iterator umIt;
for(umIt = selectedUF.userModels.begin(); umIt != selectedUF.userModels.end(); umIt++){
SqlQueryModel model = *umIt;
// Additional code removed since error happens on previous line.
}
And:
QListIterator<SqlQueryModel> umIt(selectedUF.userModels);
With both, I get a "copy constructor" error, although, I don't copy the constructor (or I don't think I do). Cf sqlquerymodel.h:
class SqlQueryModel : public QSqlQueryModel
{
Q_OBJECT
void generateRoleNames();
public:
explicit SqlQueryModel(QObject *parent = 0);
void setQuery(const QString &query, const QSqlDatabase &db = QSqlDatabase());
void setQuery(const QSqlQuery &query);
QVariant data(const QModelIndex &index, int role) const;
QHash<QString, QVariant> bindings; // Not used yet. Will be replaced by Binding class.
QString modelName;
QString query;
signals:
void bindedValueChanged();
public slots:
void search(QString);
void reset();
void updateBindings();
};
Here's the full exact error:
In file included from ..\..\..\..\Qt\4.8.4\include\QtSql/qsqlquerymodel.h:1:0,
from ..\..\..\..\Qt\4.8.4\include\QtSql/QSqlQueryModel:1,
from ..\SSL_Tool\/sqlquerymodel.h:4,
from ..\SSL_Tool\main.cpp:12:
..\..\..\..\Qt\4.8.4\include/QtCore/../../src/corelib/kernel/qabstractitemmodel.h: In copy constructor 'QSqlQueryModel::QSqlQueryModel(const QSqlQueryModel&)':
..\..\..\..\Qt\4.8.4\include\QtSql/../../src/sql/models/qsqlquerymodel.h:37:20: instantiated from 'void QList<T>::node_copy(QList<T>::Node*, QList<T>::Node*, QList<T>::Node*) [with T = SqlQueryModel]'
..\..\..\..\Qt\4.8.4\include/QtCore/../../src/corelib/tools/qlist.h:689:9: instantiated from 'void QList<T>::detach_helper(int) [with T = SqlQueryModel]'
..\..\..\..\Qt\4.8.4\include/QtCore/../../src/corelib/tools/qlist.h:703:5: instantiated from 'void QList<T>::detach_helper() [with T = SqlQueryModel]'
..\..\..\..\Qt\4.8.4\include/QtCore/../../src/corelib/tools/qlist.h:100:80: instantiated from 'QList<T>::QList(const QList<T>&) [with T = SqlQueryModel]'
..\SSL_Tool\/userform.h:17:7: instantiated from here
..\..\..\..\Qt\4.8.4\include/QtCore/../../src/corelib/kernel/qabstractitemmodel.h:338:5: error: 'QAbstractTableModel::QAbstractTableModel(const QAbstractTableModel&)' is private
..\..\..\..\Qt\4.8.4\include\QtSql/../../src/sql/models/qsqlquerymodel.h:37:20: error: within this context
In file included from ..\SSL_Tool\main.cpp:12:0:
..\SSL_Tool\/sqlquerymodel.h: In copy constructor 'SqlQueryModel::SqlQueryModel(const SqlQueryModel&)':
..\SSL_Tool\/sqlquerymodel.h:14:7: note: synthesized method 'QSqlQueryModel::QSqlQueryModel(const QSqlQueryModel&)' first required here
In file included from ..\..\..\..\Qt\4.8.4\include/QtCore/qlist.h:1:0,
from ..\..\..\..\Qt\4.8.4\include/QtCore/../../src/corelib/kernel/qobject.h:28,
from ..\..\..\..\Qt\4.8.4\include/QtCore/qobject.h:1,
from ..\..\..\..\Qt\4.8.4\include/QtCore/../../src/corelib/kernel/qcoreapplication.h:23,
from ..\..\..\..\Qt\4.8.4\include/QtCore/qcoreapplication.h:1,
from ..\..\..\..\Qt\4.8.4\include\QtGui/../../src/gui/kernel/qapplication.h:23,
from ..\..\..\..\Qt\4.8.4\include\QtGui/qapplication.h:1,
from ..\..\..\..\Qt\4.8.4\include\QtGui/QApplication:1,
from ..\SSL_Tool\main.cpp:1:
..\..\..\..\Qt\4.8.4\include/QtCore/../../src/corelib/tools/qlist.h: In member function 'void QList<T>::node_copy(QList<T>::Node*, QList<T>::Node*, QList<T>::Node*) [with T = SqlQueryModel]':
..\..\..\..\Qt\4.8.4\include/QtCore/../../src/corelib/tools/qlist.h:689:9: instantiated from 'void QList<T>::detach_helper(int) [with T = SqlQueryModel]'
..\..\..\..\Qt\4.8.4\include/QtCore/../../src/corelib/tools/qlist.h:703:5: instantiated from 'void QList<T>::detach_helper() [with T = SqlQueryModel]'
..\..\..\..\Qt\4.8.4\include/QtCore/../../src/corelib/tools/qlist.h:100:80: instantiated from 'QList<T>::QList(const QList<T>&) [with T = SqlQueryModel]'
..\SSL_Tool\/userform.h:17:7: instantiated from here
..\..\..\..\Qt\4.8.4\include/QtCore/../../src/corelib/tools/qlist.h:377:17: note: synthesized method 'SqlQueryModel::SqlQueryModel(const SqlQueryModel&)' first required here
mingw32-make[1]: Leaving directory `C:/Users/XXX/build-SSL_Tool-Desktop-Debug'
mingw32-make[1]: *** [debug/main.o] Error 1
mingw32-make: *** [debug] Error 2
Any idea why?
QSqlQueryModel (and all other QObject-derived objects) can't be copied using copy constructor. QList requires its element type to have copy constructor. So, you need to use QList<SqlQueryModel*> instead of QList<SqlQueryModel>. You should create and delete your model objects manually using new and delete.
Related
I have a class that returns a list of custom objescts, to view in qml
#include <QObject>
#include "networkinterface.h"
class Network : public QObject {
Q_OBJECT
public:
explicit Network(QObject *parent = 0);
Q_INVOKABLE QList<NetworkInterface> getNetworkAdaptors();
private:
QList<NetworkInterface> networkAdaptors; };
At main.qml i call this method as
model: network.getNetworkAdaptors()
It all was working when NetworkInterface was a struct, but when i converted it to a class, can't make it work.
Class NetworkInterface is inherited from QObject and got properties
class NetworkInterface : public QObject
{
Q_OBJECT
public:
NetworkInterface();
QString name;
QString description;
const QString &getName() const;
void setName(const QString &newName);
const QString &getDescription() const;
void setDescription(const QString &newDescription);
...
private:
Q_PROPERTY(QString name READ getName CONSTANT)
Q_PROPERTY(QString description READ getDescription CONSTANT)
};
So the error i got is :
main.cpp.o:-1: error: Undefined symbols for architecture x86_64:
"NetworkInterface::NetworkInterface()", referenced from:
QtPrivate::QMetaTypeForType<NetworkInterface>::getDefaultCtr()::'lambda'(QtPrivate::QMetaTypeInterface const*, void*)::operator()(QtPrivate::QMetaTypeInterface const*, void*) const in mocs_compilation.cpp.o
Network::getNetworkAdaptors() in network.cpp.o
_main in main.cpp.o
I suspect it is wrong type expose, as with sctruct it was working fine, how to do that correctly?
UPD: in NetworkInterface i have following constructors:
NetworkInterface();
NetworkInterface(const NetworkInterface &obj);
NetworkInterface & operator=( const NetworkInterface & obj);
Without them i can't push_back(networkInterface) to the list of interfaces, as it requires copy constructor. Also list of pointers won't work for qml as a model, it must be exactly objects list.
When i copy all code in NetworkInterface and leave only above constructors, it is minimal code that gives a error.
Default constructor was missing, adding
NetworkInterface::NetworkInterface(QObject *parent) : QObject(parent)
{
}
Resoled a problem
On C++ side, I had this method:
class MyClass : public QObject
{
Q_OBJECT
Q_INVOKABLE QVariant getFamily_byParentName(QString &parentName) const;
// ...
}
I was calling the C++ method on QML:
onButtonClicked: {
myClass.getFamily_byParentName(items3D.model[0]) // items3D.model[0] is a string
}
The above code was throwing this error at the QML line myClass.getFamily_byParentName(items3D.model[0]):
Error: Unknown method parameter type: QString&
Solution
The above error got resolved by declaring QString argument as const:
Q_INVOKABLE QVariant getFamily_byParentName(const QString &parentName) const;
The question is: why?
The QML engine converts the appropriate data types by copying the values.
In your case QString & is a reference to a QString that can not be copied, instead const QString & can be copied. For this reason you can not have a QObject as an argument since it is not copyable and instead you must use QObject * since a pointer is copyable.
It's the same principle as the Q_SIGNALs.
The common part (crating a lib) of my project currently holds a interface Class of the type:
class CanBeAddedToGroup{
public:
void addToGroup(Group& )=0;
}
Now i also wantred to use the programm on a Class containing data in a QVariant, so i started it off simple:
class DataContainingClass: public CanBeAddedToGroup{
QMap<QString,QVarient> data;
public:
void addToGroup(Group& ){
QMap<QString,QVarient>::itterator itter = data.begin();
QMap<QString,QVarient>::itterator end= data.end();
for(;itter !=end;itter ++){
<Handle Data>
}
}
};
}
Now one of the datatypes addedt to the list (outside the lib) is of the type:
class DataClass: public QObject, public CanBeAddedToGroup{
void addToGroup(Group& );
}
Q_DECLARE_METATYPE(DataClass)
And it is added to the map using "QVariant::fromValue(", now i need a way in the "DataContainingClass" to check if the Data is derived from a QObject, so i know static_cast(variant.data()) is valid.
Then i could try to dynamic_cast the Object pointer to CanBeAddedToGroup, and call it.
--- EDIT ---:
The Problem IS NOT: Having a QObject and check if it inherits another QObject, it is not even checking if a Class inherits from another one, it is to know if the data i have actually IS a QObject.
Minimal Example:
Header File:
#include <QObject>
#include <QDebug>
class DmbClass: public QObject{
Q_OBJECT
public:
DmbClass(){TST="RealOne";}
DmbClass(const DmbClass&d){TST="Clone";}
QString TST;
};
Q_DECLARE_METATYPE(DmbClass)
class Tst{
public:
virtual void tstFunct()=0;
};
class CanClass: public QObject, public Tst{
Q_OBJECT
public:
CanClass(){TST="RealOne";}
CanClass(const CanClass&d){TST="Clone";}
QString TST;
virtual void tstFunct() override{
qDebug()<<"tst";
}
};
Q_DECLARE_METATYPE(CanClass)
class DmbGadget{
Q_GADGET
public:
DmbGadget(){TST="RealOne";}
DmbGadget(const DmbGadget&d){TST="Clone";}
QString TST;
};
Q_DECLARE_METATYPE(DmbGadget)
C File:
// QObject in QVariant
DmbClass dC;
QVariant varC=QVariant::fromValue(dC);
const void* vPC = varC.data();
DmbClass dCc = varC.value<DmbClass>();
QObject* objC = (QObject*)varC.data();
QObject* schouldWork = objC->parent();
Tst* schouldBeNull = dynamic_cast<Tst*>(objC);
// Object using correct base class in QVariant
CanClass dT;
QVariant varT=QVariant::fromValue(dT);
const void* vPT = varT.data();
CanClass dTc = varC.value<CanClass>();
QObject* objT = (QObject*)varT.data();
QObject* schouldWork2 = objT->parent();
Tst* schouldNotNull = dynamic_cast<Tst*>(objT);
schouldNotNull->tstFunct();
// Q_Gadget in QVariant
DmbGadget dG;
QVariant varG=QVariant::fromValue(dG);
const void* vPG = varG.data();
DmbGadget dGg = varG.value<DmbGadget>();
QObject* objD = (QObject*)varG.data();
//QObject* schouldSegFault = objD->parent();
// base value in QVariant
QVariant var4=4;
const void* vP4 = var4.data();
QObject* obj4 = (QObject*)var4.data();
//QObject* schouldSegFault2 = obj4 ->parent();
I need a way to distinguisch cases 1&2 from 3&4 ("schouldSegFault"), without using something only defined outside of the lib.
I Already Tryed:
int tst4 = qRegisterMetaType<CanClass>("CanClass");
QMetaType help2(tst4);
But help2 has a MetaObject of 0, so i cant check for the inheriance from QObject.
Edit/for who added "Proper way to check QObject derived class type in Qt" ther was te issue in my programm that the class inherits from another QObjectclass so i cant chack for inheriance of my interface (even when defined as Q_Gadget) using inherits, since it would only be true for the first element.
PS: For everyone trying to call functions on a QVariant containing a Object rather than a pointer might be interested in this approach:
How to support comparisons for QVariant objects containing a custom type? / https://pastebin.com/tNLa0jSa
While having a global registry for types is what i wished i could avoid for the case.
Just try to use QVariant::value and see if the value in a QVariant can be converted to your target class. Here's a minimal example:
#include <QObject>
#include <QVariant>
#include <QVariantMap>
#include <QDebug>
class MyQObjectClass : public QObject {
Q_OBJECT
public:
explicit MyQObjectClass(QObject *parent = nullptr) : QObject(parent) {}
void greet() { qDebug() << "I am a MyQObjectClass!"; }
};
Q_DECLARE_METATYPE(MyQObjectClass*)
int main(int, char *[])
{
MyQObjectClass obj;
QVariantMap map;
map.insert("foo", QString("Hello World"));
map.insert("bar", QVariant::fromValue(&obj));
QVariantMap::iterator iter = map.begin();
QVariantMap::iterator end= map.end();
for(;iter !=end;iter ++) {
auto value = iter.value();
// Try to convert to MyQObjectClass*
auto obj = value.value<MyQObjectClass*>();
if (obj != nullptr) {
qDebug() << iter.key() << "is an instance of MyQObjectClass";
obj->greet();
continue;
}
qDebug() << iter.key() << "is not an instance of MyQObjectClass";
}
}
#include "main.moc"
Running it should yield the following output on the console:
"bar" is an instance of MyQObjectClass
I am a MyQObjectClass!
"foo" is not an instance of MyQObjectClass
The important parts:
Make sure the class you want to store in a QVariant derives from QObject and has the Q_OBJECT macro.
When iterating over the map, use QVariant::value() and try to convert the contained value to your target class. In the example, I use QVariant::value<MyQObjectClass*>() - according to the documentation, this either returns the contained instance of MyQObjectClass* if the value can be converted to it or - which is the case if the QVariant contains either basic values or gadgets - a default constructed value. In the case of a pointer this would be a null pointer, so just check if the value returned is null. That's it.
Never work on Qvariant::data() directly.
Update
Just as a remark: The Qobject class declared the copy constructor and assignment operators as private:
From the official documentation:
QObject has neither a copy constructor nor an assignment operator. This is by design. Actually, they are declared, but in a private section with the macro Q_DISABLE_COPY(). In fact, all Qt classes derived from QObject (direct or indirect) use this macro to declare their copy constructor and assignment operator to be private. The reasoning is found in the discussion on Identity vs Value on the Qt Object Model page.
Hence, you cannot copy around instances of QObject (and consequentially you cannot store them in QVariant). Instead, you pass around pointers to QObject instances.
Update #2
If your interface class cannot derive directly from QObject, you might consider using Qt's plugin mechanism instead. Here's the above example slightly edited to fit this approach:
#include <QObject>
#include <QVariant>
#include <QVariantMap>
#include <QDebug>
class MyInterfaceClass {
public:
MyInterfaceClass() {}
virtual ~MyInterfaceClass() {}
virtual void greet() = 0;
};
#define MyInterfaceClass_IID "org.example.MyInterfaceClass"
Q_DECLARE_INTERFACE(MyInterfaceClass, MyInterfaceClass_IID)
class MyConcreteClass : public QObject, public MyInterfaceClass {
Q_OBJECT
Q_INTERFACES(MyInterfaceClass)
public:
MyConcreteClass(QObject *parent = nullptr) : QObject(parent) {}
void greet() override { qDebug() << "I am a MyInterfaceClass!"; }
};
int main(int, char *[])
{
MyConcreteClass obj;
QVariantMap map;
map.insert("foo", QString("Hello World"));
map.insert("bar", QVariant::fromValue(&obj));
QVariantMap::iterator iter = map.begin();
QVariantMap::iterator end= map.end();
for(;iter !=end;iter ++) {
auto value = iter.value();
// Try to convert to QObject*:
auto obj = value.value<QObject*>();
if (obj != nullptr) {
// Try if we can cast to our interface class:
auto ifc = qobject_cast<MyInterfaceClass*>(obj);
if (ifc != nullptr) {
qDebug() << iter.key() << "is an instance of MyInterfaceClass";
ifc->greet();
}
continue;
}
qDebug() << iter.key() << "is not an instance of MyInterfaceClass";
}
}
#include "main.moc"
You need to:
Define your interface class and register it with Qt using the Q_DECLARE_INTERFACE macro.
Declare your concrete classes, deriving from QObject and your interface class. In addition, you need to tell Qt about the interface part using the Q_INTERFACES macro.
When checking the values in your map, first try to convert to a QObject* via QVariant::value(). If this succeeds, you can try to qobject_cast to your interface class.
Your design is completely broken: QObjects cannot be used as unrestricted values. They cannot be copied nor moved, and your implementations of copy constructors are hiding this fundamental fact.
I know that I can use QMetaType to create an object without parameters.
Another possible option is to use QMetaObject and call newInstance. But I need to get QMetaObject from something.
I tried to use QMetaType::metaObjectForType, but it always returns null pointer (but QMetaType is able to create the object).
QMetaObject const* metaObject = QMetaType::metaObjectForType(id); // return null pointer
QObject* object = (QObject*)QMetaType::create(id); // create the object
QMetaObject const* metaObject = object->metaObject(); // return not-null pointer
UPDATE:
I think the question is why metaObjectForType does not work for me.
The class is registered with qRegisterMetaType, also Q_DECLARE_METATYPE and Q_OBJECT are applied.
First of all, to pass parameters to methods, you needs some kind of reflection framework beyond plain C++. With Qt, the obivous choice is Qt Meta Object system with it's QMetaObject, though then you must derive your classes for QObject. After that, you need to do two things:
1. make constructor invokable
Signals and slots are invokable by default, but any other method you want to invoke through the meta object system needs to be explicitly marked as such. Example myqobject.h:
#ifndef MYQOBJECT_H
#define MYQOBJECT_H
#include <QObject>
class MyQObject : public QObject
{
Q_OBJECT
public:
Q_INVOKABLE MyQObject(QObject *parent = 0); // tested with empty constructor in .cpp
};
#endif // MYQOBJECT_H
2. create your own mapping from class name string to the QMetaObject
QMetaType doc says: "any class or struct that has a public default constructor, a public copy constructor, and a public destructor can be registered." This rules out QObject, because they can't have copy constructors. You need to create your own mapping from name to the meta object. An example shown in this main.cpp:
#include <QCoreApplication>
#include <QtCore>
#include "myqobject.h"
// a global map for mapping strings to QMetaObjects,
// you need header file like this if you want to access it from other .cpp files:
//
// #include <QHash>
// #include <QString>
// class QMetaObject; // forward declaration, enough when only pointer is needed
// extern QHash<QString, const QMetaObject*> metaObjs;
//
QHash<QString, const QMetaObject*> metaObjs;
// optional: create a macro to avoid typing class name twice,
// #c surrounds macro argument with double quotes converting it to string
#define METAOBJS_INSERT(c) (metaObjs.insert(#c, &c::staticMetaObject))
int main()
{
METAOBJS_INSERT(MyQObject);
const QMetaObject *meta = metaObjs["MyQObject"];
qDebug() << "Class name from staticMetaObject: " << meta->className();
QObject *o = meta->newInstance(); // add constructor arguments as needed
MyQObject *mo = qobject_cast<MyQObject*>(o);
if (mo) qDebug() << "Class name from object instance: " << mo->metaObject()->className();
else qDebug() << "Instance creation failed or created wrong class!";
return 0;
}
If you do not want to use QObject, then you need to come up with some similar (probably lighter-weight and without separate compiler step) mechanism of your own.
I had the same problem.
The solution is in two steps:
call qRegisterMetaType() with a pointer type:
qRegisterMetaType<MyClass*>(). this will give you a valid
QMetaObject with call of QMetaType::metaObjectForType(id);
make your constructor Q_INVOKABLE. this will enable a valid call to
QMetaObject::newInstance
And also be sure that your class is derived from QObject and have a Q_OBJECT macro in it.
class A : public QObject
{
Q_OBJECT
public:
A(const A&) {}; // dummy copy contructor that do nothing to disable error message
Q_INVOKABLE A(int test_value = 99999) : TestValue(test_value) {};
int TestValue;
};
Q_DECLARE_METATYPE(A);
int main(int argc, char *argv[])
{
qRegisterMetaType<A>(); //you do not need this
qRegisterMetaType<A*>();//the real registration
int type_id_for_A = QMetaType::type("A"); // valid type id (in my case = 403)
const QMetaObject *meta_object_for_A = QMetaType::metaObjectForType(type_id_for_A); // returns NULL
int type_id_for_A_ptr = QMetaType::type("A*"); // valid type id (in my case = 404)
const QMetaObject *meta_object_for_A_tr = QMetaType::metaObjectForType(type_id_for_A_ptr); // returns NOT NULL
A* A_obj= dynamic_cast<A*>(meta_object_for_A_tr->newInstance(Q_ARG(int, 12345)));
int test_value = A_obj->TestValue; // returns 12345, not 99999
}
I've got a class applicationManager that ought to emit signal when there is an info message or an error occurs, while I'm suppose to log that messages consuming it by QXmppLogger class object. There is a QXmppLoggable class that got methods like info() and warning() that emits a signal logmessage() of internal QXmppLogger. So, in order to emit a signal I've inherited QXmppLogable class which inherits QObject itself, hence to be able to use info() and warning() and connected emitted SIGNAL(logmessage()) by info() and warning() methods, to SLOT (log()) of QXmppLogger object. Here is the code snippet:
header "imApplicationManager.h"
class applicationManagement: public QXmppLoggable
{
//Q_OBJECT
public:
bool createDataBaseConnection();
applicationManagement();
~applicationManagement();
void setLogger(QXmppLogger *logger);
private:
QXmppLogger *logger;
};
and related "imApplicationManager.cpp"
applicationManagement::applicationManagement()
{
QObject::connect(this, SIGNAL(logMessage(QXmppLogger::MessageType,QString)),
logger, SLOT(log(QXmppLogger::MessageType,QString)));
}
applicationManagement::~applicationManagement()
{
// db..closing
}
bool applicationManagement::createDataBaseConnection(){
//...database conncetion...
if (!dataBase.open()){
warning(QString("Cannot open database %1").arg(dataBase.lastError().text()));
qDebug()<< "Cannot open database " << dataBase.lastError();
return false;
}
info(QString("Database succeeded!"));
return true;
}
void applicationManagement::setLogger(QXmppLogger *logger)
{
if(this->logger != logger)
this->logger = logger;
}
in the main.cpp
#include "imApplicationManager"
#incLude "QXmppLogger"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
applicationManagement aa;
QXmppLogger log;
aa.setLogger(&log);
return a.exec();
}
Compilation informs of no error but when luanched there is a Sigmentation fault.
How can I fix that?
OK, decided to post a full answer:
First of all, you do NEED the Q_OBJECT macro. The errors you get from it will likely disappear when you Clean All, Run qmake and Rebuild All from the Build menu of QtCreator. Qt relies on a LOT of generated boilerplate code you never have to type, and without Q_OBJECTthat code will not be generated. That is the reason you sometimes need to clean up after you made changes, run qmake (which generates the code) and rebuild with the now up-to-date generated code.
Second - in the constructor of applicationManagement you connect to an uninitialized pointer logger. This is probably why you get segmentation fault. You can use two approaches to fix that:
Pass the pointer to the logger in the constructor of applicationManagement, this way you have something to connect to in the constructor. This way you cannot instantiate an applicationManagement before a logger, unless you use logger(new QXmppLogger) in the constructor initialization list.
Move the connection from the applicationManagement constructor to the setLogger()method. Do not forget to disconnect a previous connection if any.
It has been mentioned that the Q_OBJECT macro is needed, but I think a little explanation would be useful too, as understanding why it's needed helps to remember to use it.
Qt adds to C++, amongst other features, the functionality of signals and slots and this is done with the Meta-Object Compiler (or moc for short). When compiling Qt code, the moc parses the header files and creates source code for you, which can be seen in the moc files. Occasionally these get out of sync and cleaning these files will fix this issue.
If you look more closely at the Q_OBJECT macro, it is defined as this: -
#define Q_OBJECT \
public: \
Q_OBJECT_CHECK \
static const QMetaObject staticMetaObject; \
virtual const QMetaObject *metaObject() const; \
virtual void *qt_metacast(const char *); \
QT_TR_FUNCTIONS \
virtual int qt_metacall(QMetaObject::Call, int, void **); \
private: \
Q_DECL_HIDDEN_STATIC_METACALL static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **); \
struct QPrivateSignal {};
As can be seen here, the Q_OBJECT macro adds function definitions to the class and its the implementation of these in the QObject parent class that provides the added C++ features such as signals / slots, properties, RTTI etc. When calling signals and slots, internally Qt uses the qt_metacall function. There's an interesting explanation of the implementation of these here. Therefore without the Q_OBJECT macro in a class derived from QObject, signals and slots won't work.
You use logger but it is not initialized before:
QObject::connect(this, SIGNAL(logMessage(QXmppLogger::MessageType,QString)),
logger, SLOT(log(QXmppLogger::MessageType,QString)));
try to rewrite your constructor like that:
applicationManagement::applicationManagement(QXmppLogger *logger_):
logger(logger_)
{
QObject::connect(this, SIGNAL(logMessage(QXmppLogger::MessageType,QString)),
logger, SLOT(log(QXmppLogger::MessageType,QString)));
}
or connect that signal after initializing logger.