Processing of Q_OBJECT in legacy non qmake build? - c++

I have a legacy build that doesn't use qmake but I'd like to add QUdpSocket and connect it with a signal and a slot. I have a single class that uses Q_OBJECT. What do I need to do to properly process the Q_OBJECT directive if I want signals and slots to be available but I am not using qmake.
Can I just substitute the original myclass.h file with the output of the "$moc myclass.h"? Or is the output in addition to the original file?
Is this the likely new make directives?
m_myclass.h : myclass.h
moc myclass.h > m_myclass.h

The MOC actually generates .cpp files to be compiled along with the rest of the project; so, that would be more something like:
moc_myclass.cpp: myclass.h
moc myclass.h > moc_myclass.cpp
moc_myclass.o: moc_myclass.cpp
g++ ${CFLAGS} moc_myclass.cpp -o moc_myclass.o // whatever
and then add moc_myclass.o to the linking step of your final executable.

Related

Qt: Define Q_OBJECT inside namespace [duplicate]

I'm using Code::Blocks 8.02 and the mingw 5.1.6 compiler. I'm getting this error when I compile my Qt project:
C:\Documents and Settings\The
Fuzz\Desktop\GUI\App_interface.cpp|33|undefined
reference to `vtable for AddressBook'
File AddressBook.h:
#ifndef ADDRESSBOOK_H
#define ADDRESSBOOK_H
#include <QWidget>
class QLabel;
class QLineEdit;
class QTextEdit;
class AddressBook : public QWidget
{
Q_OBJECT
public:
AddressBook(QWidget *parent = 0);
private:
QLineEdit *nameLine;
QTextEdit *addressText;
};
#endif
File AddressBook.cpp:
#include <QtGui>
#include "addressbook.h"
AddressBook::AddressBook(QWidget *parent)
: QWidget(parent)
{
QLabel *nameLabel = new QLabel(tr("Name:"));
nameLine = new QLineEdit;
QLabel *addressLabel = new QLabel(tr("Address:"));
addressText = new QTextEdit;
QGridLayout *mainLayout = new QGridLayout;
mainLayout->addWidget(nameLabel, 0, 0);
mainLayout->addWidget(nameLine, 0, 1);
mainLayout->addWidget(addressLabel, 1, 0, Qt::AlignTop);
mainLayout->addWidget(addressText, 1, 1);
setLayout(mainLayout);
setWindowTitle(tr("Simple Address Book"));
}
When using Qt Creator:
Build → Run qmake
Build → Rebuild All
Warning: Do not do this if you already have a .pro file - you'll lose it!
In order to automatically ensure that all moc cpp files are generated, you can get qmake to automatically generate a .pro file for you instead of writing one yourself.
Run
qmake -project
in the project directory, and qmake will scan your directory for all C++ headers and source files to generate moc cpp files for.
The problem is almost certainly that you are not compiling or not linking in the generated moc_AddressBook.cpp file. (It should have been generated for you -- you are running Qt's moc on your code before compiling, right?)
To answer a little more thoroughly, the Q_OBJECT macro signals Qt's moc tool to create an extra implementation file that contains the code necessary to support QObject's meta-information system. If you had any signals or slots, it would do a few things for those as well.
An alternative solution might be to remove the Q_OBJECT macro. You probably don't want to do this, but it would help the immediate problem, and it isn't strictly necessary with the code that you've presented.
Also, I would note that your line:
#include "addressbook.h"
Should probably be:
#include "AddressBook.h"
based on how you presented the filenames in the question.
Assuming you are using qmake to generate your Makefile, be sure that AddressBook.h is specified in your .pro file's HEADERS's variable, e.g.
HEADERS = AddressBook.h
For CMake projects, set CMAKE_AUTOMOC to ON, this fixed my problem.
#Find includes in corresponding build directories
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# Instruct CMake to run moc automatically when needed.
set(CMAKE_AUTOMOC ON)
I got this while using pure virtual functions. For example,
virtual void process();
gave this error, while
virtual void process() = 0;
made it go away.
For anyone who's Googling this problem, check that all virtual functions are defined. (via " = 0" or a full definition in the source file)
I'm using Netbeans with the MinGW compiler.
I was running into the same problem using CLion, and solved it by adding these lines to CMakeLists.txt
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
See https://www.jetbrains.com/help/clion/qt-tutorial.html#qt-setup-in-clion
I had the same problem but as soon as I defined my constructor in the header file instead of the .cpp the error disappeared. Also the corresponding moc file was missing in the file system and in the Makefile section"compiler_moc_header_make_all" . I ran a qmake then finally everything built with succes. I went to check the Makefile and it was there now.
deleted the build folder, restarted Qt Creator and it worked
I come to the same problem, rebuild the project never update the Makefile, I remove the Makefile and rebuild , the the problem is gone.
ps: run 'make' from command line may give you detail information than the IDE, and helpful to get the real problem.
One cause is when you declare a virtual functions in a class and you don't define their body.
In my case Rebuild All was not enough, I had to delete build directory and make Rebuild All - then it worked!
Simply Run qmake for your project. This can easily be done by right-clicking on the name of your project and clicking on Run qmake.
Just clear the project and then rebuild it!
Go to .pro file and make sure .h file has 'include' before it.
HEADERS += include/file.h \
include/file2.h
I had the same problem trying to use a protected virtual function. Two things worked.
Changing void process(); to void process() = 0;
Making process() public instead of private
You will get the same error message if you accidentally add a destructor prototype. Add an empty destructor definition or remove the prototype.
Header files for moc compilation should contained in the HEADERS += ... variable:
I have moved the header files in the Myproject.pro to the SOURCES += ... section, because I want to have mySource.h and mySource.cpp in the same tree element. But that is faulty for QT Creator. In result the error "Undefined reference to vtable" has occured.
It seems to be:
QT detects header for moc compilation only in the HEADERS +=... section (or variable).
See also the correct explaination in the other stackoverflow answer Second anwer "I've seen a lot of ways to solve the problem, but no explanation for why it happens, so here goes.". In my mind this is an exactly explaination of the problem, which has help me to found and solve my problem.
CMake
when using CMake, interestingly enough if my .cpp and .h files are not in the same folder the moc, bu default, fails to generate the meta file :)
the most errors from using Q_OBJECT but not generate moc file
the moc file define
classname::metaObject
staticMetaObject
qt_metacall
Here is a example:
when source or header using Q_OBJECT
/opt/qt/bin/moc ./window.h -o ./moc_window.cpp
Makefile add moc_window.o in OBJS
Ex: OBJS=main.o window.o moc_window.o
try this source
https://www.mediafire.com/file/anjeah1jmm07mfe/qt_group_box.tar.gz
refer to http://fatalfeel.blogspot.com/2013/11/qt5-c-building.html
I am using Qt creator to compile and run my programs, I don't use Qt command prompt often. One thing I did to get rid of the annoying error "vtable something something" is by adding the following lines to .pro file.
TEMPLATE = app
QT += core

Why is important to include ".moc" file at end of a Qt Source code file?

Why is it important to add an include for .moc file in a Qt cpp source code?
This is a common step used in several Qt samples, including this one:
http://doc.qt.io/qt-5/qttestlib-tutorial1-example.html; where the line #include "testqstring.moc" should be included in the end of the file.
I don't understand exactly why this is necessary.
It's necessary if you define QObject subclasses with the Q_OBJECT macro in a .cpp file. When you do so:
qmake must generate rules inside your Makefile to invoke moc on that .cpp file.
That special (hackish?) inclusion triggers qmake to do so, and tells it which would be moc's output file (teststring.moc) when invoked on your .cpp.
In order to compile moc's output (which is still a bunch of C++ code) the compiler must see your class definition. Otherwise, it will complain that there's no such thing as YourClass::staticMetaObject and similar, because it has no idea that YourClass exists.
Typically one defines classes featuring Q_OBJECT in a header file. moc then adds a #include "header.h" into its generated output, and this means moc's output can be happily compiled.
But what if your class definition is inside a .cpp? You can't #include a .cpp file in moc's output, as that would give you tons of redefinition errors.
Instead, you #include moc's output in your .cpp, so that it gets compiled together and everyone is happy. (This means qmake will only emit one rule saying to run moc, but not another rule telling the compiler to compile moc's output.)
From 2. you can also also desume that defining classes with Q_OBJECT in a .h does not require any special inclusion.
Make an addition:
When Q_OBJECT in xxx.h, after qmake, the system will generate a moc_xxx.cpp with xxx.h in it.
When Q_OBJECT in xxx.cpp, after qmake, the system will generate a xxx.moc, and you need to add the .moc file into the .cpp file.

Qt Q_OBJECT class compilation

What is needed for errorfree compilation when adding a class that is flagged as
Q_OBJECT
? Should one run qmake file ?
New classes are written in .h .cpp files that are already added in .pro .pri files.
My metaphysics questions are
1/ is qmke_all.bat run and rebuild all enough to have Qt dependencies cleared up ? if not, what is procedure ?
2/ why is this procedure needed, what happens?
3/ what are .pro .pri for ? are both of them here for 'mapping' with qt ? should i change anything to them when adding classes but no .h .cpp files ?
I am with VS2010
thanks
If you've added Q_OBJECT to a self-defined class you need to run qmake prior to compilation, otherwise it won't generated the meta code needed for it.
1) Not sure what you mean here, sorry.
2) Or here.
3) The .pro and .pri are essentially directives files for qmake, much the same way Makefiles work for make. There's obvious differences, but you're not far off when you say they're for mapping, they're there to tell qmake how to generate the necessary compilation files. When you're adding new classes if they've not been auto-added then you need to add both the .cpp & .h files.

Cannot compile MOC file if Q_OBJECT macro is removed by other macro: The header file doesn't include <QObject>

When compiling a non-Qt version of a Qt/C++ program (-DDISABLE_MYMODULE), I get this compiler error:
src/mymodule.moc.cpp:12:2: error: #error "The header file
'mymodule.hpp' doesn't include <QObject>."
src/mymodule.moc.cpp:19:1: error: ‘QT_BEGIN_MOC_NAMESPACE’ does not name a type
src/mymodule.moc.cpp:40:6: error: ‘MyModule’ has not been declared
...
I'm using GNU make (not qmake). My Makefile compiles two object files per module, one directly from the .cpp source file and the MOC object file from the .moc.cpp source file (this is what doesn't work), both using g++. This .moc.cpp source file is created by MOC, from the .hpp header (this process does not throw an error).
The header file in question looks somewhat like this:
#ifndef DISABLE_MYMODULE //My problem macro
#ifndef MYMODULE_HPP
#define MYMODULE_HPP
//...
class MyModule : //...
{
Q_OBJECT //Qt problem macro
//...
};
//...
#endif
#endif
The whole thing will compile (and later link, execute) just fine if don't set my problem macro. If I do set it, but comment out QT's problem macro, it'll compile fine as well (building a non-Qt version).
I don't exactly know, what MOC replaces Q_OBJECT by, but shouldn't it still be inside my DISABLE_MYMODULE and therefore be removed by the preprocessor?
It looks like with your macro DISABLE_MYMODULE you exclude class definition, which includes Q_OBJECT. On the other hand, this code still processed by moc tool, which generates your mymodule.moc.cpp file, which in turn includes your mymodule.hpp header file. When mymodule.moc.cpp is then processed by compiler it includes .hpp file, but preprocessor excludes its content because of DISABLE_MYMODULE, so compiler do not find definition of the class, #include <QObject> and things to which Q_OBJECT macro should be expanded. So compiler do not find the things, which it expects to be and becom upset...
I think, the solution will be to exclude mymodule.moc.cpp from build if DISABLE_MYMODULE is defined or (better) disable moc processing on mymodule.hpp, if DISABLE_MYMODULE is defined.
Try to check next criterias:
Class should be inherit from QObject directly or indirectly, and QObject must be first in the inheritance list.
Class is defined and implemented in separate *.h and *.cpp files. If not, you need to add #include "you_cpp_file.moc" to end of the file where class is implemented and defined.

Undefined reference to vtable. Trying to compile a Qt project

I'm using Code::Blocks 8.02 and the mingw 5.1.6 compiler. I'm getting this error when I compile my Qt project:
C:\Documents and Settings\The
Fuzz\Desktop\GUI\App_interface.cpp|33|undefined
reference to `vtable for AddressBook'
File AddressBook.h:
#ifndef ADDRESSBOOK_H
#define ADDRESSBOOK_H
#include <QWidget>
class QLabel;
class QLineEdit;
class QTextEdit;
class AddressBook : public QWidget
{
Q_OBJECT
public:
AddressBook(QWidget *parent = 0);
private:
QLineEdit *nameLine;
QTextEdit *addressText;
};
#endif
File AddressBook.cpp:
#include <QtGui>
#include "addressbook.h"
AddressBook::AddressBook(QWidget *parent)
: QWidget(parent)
{
QLabel *nameLabel = new QLabel(tr("Name:"));
nameLine = new QLineEdit;
QLabel *addressLabel = new QLabel(tr("Address:"));
addressText = new QTextEdit;
QGridLayout *mainLayout = new QGridLayout;
mainLayout->addWidget(nameLabel, 0, 0);
mainLayout->addWidget(nameLine, 0, 1);
mainLayout->addWidget(addressLabel, 1, 0, Qt::AlignTop);
mainLayout->addWidget(addressText, 1, 1);
setLayout(mainLayout);
setWindowTitle(tr("Simple Address Book"));
}
When using Qt Creator:
Build → Run qmake
Build → Rebuild All
Warning: Do not do this if you already have a .pro file - you'll lose it!
In order to automatically ensure that all moc cpp files are generated, you can get qmake to automatically generate a .pro file for you instead of writing one yourself.
Run
qmake -project
in the project directory, and qmake will scan your directory for all C++ headers and source files to generate moc cpp files for.
The problem is almost certainly that you are not compiling or not linking in the generated moc_AddressBook.cpp file. (It should have been generated for you -- you are running Qt's moc on your code before compiling, right?)
To answer a little more thoroughly, the Q_OBJECT macro signals Qt's moc tool to create an extra implementation file that contains the code necessary to support QObject's meta-information system. If you had any signals or slots, it would do a few things for those as well.
An alternative solution might be to remove the Q_OBJECT macro. You probably don't want to do this, but it would help the immediate problem, and it isn't strictly necessary with the code that you've presented.
Also, I would note that your line:
#include "addressbook.h"
Should probably be:
#include "AddressBook.h"
based on how you presented the filenames in the question.
Assuming you are using qmake to generate your Makefile, be sure that AddressBook.h is specified in your .pro file's HEADERS's variable, e.g.
HEADERS = AddressBook.h
For CMake projects, set CMAKE_AUTOMOC to ON, this fixed my problem.
#Find includes in corresponding build directories
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# Instruct CMake to run moc automatically when needed.
set(CMAKE_AUTOMOC ON)
I got this while using pure virtual functions. For example,
virtual void process();
gave this error, while
virtual void process() = 0;
made it go away.
For anyone who's Googling this problem, check that all virtual functions are defined. (via " = 0" or a full definition in the source file)
I'm using Netbeans with the MinGW compiler.
I was running into the same problem using CLion, and solved it by adding these lines to CMakeLists.txt
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
See https://www.jetbrains.com/help/clion/qt-tutorial.html#qt-setup-in-clion
I had the same problem but as soon as I defined my constructor in the header file instead of the .cpp the error disappeared. Also the corresponding moc file was missing in the file system and in the Makefile section"compiler_moc_header_make_all" . I ran a qmake then finally everything built with succes. I went to check the Makefile and it was there now.
deleted the build folder, restarted Qt Creator and it worked
I come to the same problem, rebuild the project never update the Makefile, I remove the Makefile and rebuild , the the problem is gone.
ps: run 'make' from command line may give you detail information than the IDE, and helpful to get the real problem.
One cause is when you declare a virtual functions in a class and you don't define their body.
In my case Rebuild All was not enough, I had to delete build directory and make Rebuild All - then it worked!
Simply Run qmake for your project. This can easily be done by right-clicking on the name of your project and clicking on Run qmake.
Just clear the project and then rebuild it!
Go to .pro file and make sure .h file has 'include' before it.
HEADERS += include/file.h \
include/file2.h
I had the same problem trying to use a protected virtual function. Two things worked.
Changing void process(); to void process() = 0;
Making process() public instead of private
You will get the same error message if you accidentally add a destructor prototype. Add an empty destructor definition or remove the prototype.
Header files for moc compilation should contained in the HEADERS += ... variable:
I have moved the header files in the Myproject.pro to the SOURCES += ... section, because I want to have mySource.h and mySource.cpp in the same tree element. But that is faulty for QT Creator. In result the error "Undefined reference to vtable" has occured.
It seems to be:
QT detects header for moc compilation only in the HEADERS +=... section (or variable).
See also the correct explaination in the other stackoverflow answer Second anwer "I've seen a lot of ways to solve the problem, but no explanation for why it happens, so here goes.". In my mind this is an exactly explaination of the problem, which has help me to found and solve my problem.
CMake
when using CMake, interestingly enough if my .cpp and .h files are not in the same folder the moc, bu default, fails to generate the meta file :)
the most errors from using Q_OBJECT but not generate moc file
the moc file define
classname::metaObject
staticMetaObject
qt_metacall
Here is a example:
when source or header using Q_OBJECT
/opt/qt/bin/moc ./window.h -o ./moc_window.cpp
Makefile add moc_window.o in OBJS
Ex: OBJS=main.o window.o moc_window.o
try this source
https://www.mediafire.com/file/anjeah1jmm07mfe/qt_group_box.tar.gz
refer to http://fatalfeel.blogspot.com/2013/11/qt5-c-building.html
I am using Qt creator to compile and run my programs, I don't use Qt command prompt often. One thing I did to get rid of the annoying error "vtable something something" is by adding the following lines to .pro file.
TEMPLATE = app
QT += core