I know the question have been asked tons of times but I can't find the solution here nor in google.
Here's my header file
#ifndef MAINCONTROLLER_H
#define MAINCONTROLLER_H
#include <QSettings>
#include <QDebug>
#include <QDir>
#include <QObject>
#include "PhTools/PhString.h"
#include "PhStrip/PhStripDoc.h"
class MainController : public QObject
{
Q_OBJECT
public:
explicit MainController(QObject *parent = 0);
void loadSettings();
PhString getLastFile();
void setLastFile(PhString fileName);
bool openDoc(PhString fileName);
signals:
void docChanged();
private:
QSettings * _settings;
PhStripDoc * _doc;
};
#endif // MAINCONTROLLER_H
And my CPP file :
#include "MainController.h"
MainController::MainController(QObject *parent) :
QObject(parent)
{
_doc = new PhStripDoc();
loadSettings();
}
void MainController::loadSettings()
{
_settings = new QSettings(QDir::homePath() + "/Library/Preferences/com.me.me.plist", QSettings::NativeFormat);
getLastFile();
}
PhString MainController::getLastFile()
{
qDebug() << "lastfile :" << _settings->value("last_file", "").toString();
return _settings->value("last_file").toString();
}
bool MainController::openDoc(PhString fileName)
{
bool succeed = _doc->openDX(fileName);
if (succeed)
emit docChanged();
return succeed;
}
void MainController::setLastFile(PhString filename)
{
_settings->setValue("last_file", filename);
}
And here's the error log :
Undefined symbols for architecture x86_64:
"MainController::docChanged()", referenced from:
MainController::openDoc(QString) in MainController.o
"vtable for MainController", referenced from:
MainController::MainController(QObject*) in MainController.o
MainController::MainController(QObject*) in MainController.o
NOTE: a missing vtable usually means the first non-inline virtual member function has no definition.
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
It might come from signals but I'm not sure...
When the Q_OBJECT macro is added after the code has already been compiled, qmake has to be run again. This will add the creation and compilation of MainController.moc to your Makefile thus preventing the linker error.
You need to include this line at the end of your source file:
#include "MainController.moc"
Alternatively, you can also handle this with your buildsystem, but that is probably the former is easier.
Related
I need to capture emited signals from a QProcess for testing purposes.
Since I am using a console application, I resolved to create a class in my main.cpp file called myObj using mainly this example:
#include <QCoreApplication>
#include <QLoggingCategory>
#include <QTextStream>
#include <QProcess>
#include <QString>
#include <QVariant>
#include <QDebug>
#include <QObject>
class myObj : public QObject
{
Q_OBJECT
public:
myObj(QObject *parent = 0);
// virtual ~Communicate();
~myObj();
public slots:
void registerFinished(int signal);
void registerAboutToClose();
void registerChannelReadyRead(int signal);
void registerReadChannelFinished();
void registerReadyRead();
void registerReadyReadStandardOutput();
void registerStarted();
};
myObj::myObj(QObject *parent)
: QObject(parent) <--- LINE 72 Error
{
}
//virtual myObj::~Communicate(){
//}
myObj::~myObj(){ <--- LINE 81 Error
}
void myObj::registerFinished(int signal){
qDebug() << "exit code = " << QString::number(signal);
}
void myObj::registerAboutToClose(){
qDebug() << "aboutToClose";
}
void myObj::registerChannelReadyRead(int signal){
qDebug() << "channelReadyRead = " << QString::number(signal);
}
void myObj::registerReadChannelFinished(){
qDebug() << "readChannelFinished";
}
void myObj::registerReadyRead(){
qDebug() << "exit code";
}
void myObj::registerReadyReadStandardOutput(){
qDebug() << "exit code";
}
void myObj::registerStarted(){
qDebug() << "started";
}
myObj *myO;
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
myO = new myObj();
//....
}
Problem:
main.cpp:72: error: undefined reference to `vtable for myObj'
main.cpp:81: error: undefined reference to `vtable for myObj'
I have looked at a number of SO pages e.g here and here and here and various others, yet had not found a solution
I have tried/done:
added the Q_Object Macro
ran qmake
rebuilt
checked the #include
.pro file
QT += core
QT -= gui
CONFIG += c++11
TARGET = serv_app
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp
Any suggestions?
You have two options:
#eyllanesc solution works for sure.
add the line #include "main.moc" before or after you main() function.
When you put the class into its own header file, qmake will generate the proper moc file.
But when you put the class into a .cpp file, the moc code is not generated unless you put the line I said before.
Update #1
In the Qt tutorial about writing a Unit Test we can find the following info:
Note that if both the declaration and the implementation of our test
class are in a .cpp file, we also need to include the generated moc
file to make Qt's introspection work.
So this is another example where we need to include the moc file.
I have the following classes ( Enemy class is the parent class and Boss and SuperDuperBoss are children classes). My problem with SuperDuperBoss
#ifndef _ENEMY_H
#define _ENEMY_H
#include <iostream>
class Enemy
{
public:
void SelectAnimation();
inline void runAI()
{
std::cout << "RunAI() is running ...\n";
}
private:
int m_iHiPoints;
};
#endif
and this is the children classes
#ifndef BOSS_H
#define BOSS_H
#include "Enemy.h"
class Boss : public Enemy
{
public:
void runAI();
};
class SuperDuperBoss : public Boss
{
public:
void runAI();
};
#endif
This is the main.cpp
#include "Enemy.h"
#include "Boss.h"
int main()
{
Enemy enemy1;
Boss boss1;
SuperDuperBoss supBoss;
enemy1.runAI();
boss1.runAI();
supBoss.runAI(); // <--- Error: linking
return 0;
}
I have a linking error.
Undefined symbols for architecture x86_64:
"SuperDuperBoss::runAI()", referenced from:
_main in main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [test] Error 1
Only declare runAI in the derived classes if you want to override the parent's definition. So, assuming you want to use the definition from Enemy, your derived classes should look like this:
class Boss : public Enemy
{
public:
//other bossy stuff
};
class SuperDuperBoss : public Boss
{
public:
//other superduperbossy stuff
};
I have a Qt project made by Qt creator.
I let the creator itself generate a private slots function fx. on_pushbutton_clicked().
This function is declared in header, the function itself is in the cpp file created by the Qt creator.
When I move the function from cpp file generated by Qt creator to another cpp file (it is added in the project, it has the same includes as the generated cpp.
When I try to compile it, I get lnk2019 error.
Is there any way to have slots functions in different files?
I am using VC compiler.
Okay, here is extract from the code. (it is quite long)
gui.h
#ifndef GUI_H
#define GUI_H
#include <QMainWindow>
#include "buffer.h"
#include <string>
#include <map>
#include <math.h>
#include <sstream>
#include <stdlib.h>
#include "qcustomplot.h"
#include <limits>
#include <time.h>
#include <random>
namespace Ui {
class GUI;
}
class GUI : public QMainWindow
{
Q_OBJECT
public:
explicit GUI(QWidget *parent = 0);
~GUI();
private slots:
void on_setall_clicked();
void on_integrace_button_clicked();
void on_elipsy_button_clicked();
void on_grafy_button_clicked();
private:
Ui::GUI *ui;
};
#endif // GUI_H
gui.cpp
#include "gui.h"
#include "ui_gui.h"
double drand(double from, double to){
double f = (double)rand()/RAND_MAX;
return from + f * (to - from);
}
GUI::GUI(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::GUI)
{
ui->setupUi(this);
srand(time(0));
}
GUI::~GUI()
{
delete ui;
}
void GUI::on_setall_clicked(){...};
void GUI::on_grafy_button_clicked(){...};
void GUI::on_integrace_button_clicked(){...};
elipsy.cpp
#include "gui.h"
void GUI::on_elipsy_button_clicked(){...};
GUI.pro
#-------------------------------------------------
#
# Project created by QtCreator 2013-03-27T09:01:31
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport
TARGET = GUI
TEMPLATE = app
SOURCES += main.cpp\
gui.cpp \
solve_rpn.cpp \
shunting_yard.cpp \
qcustomplot.cpp \
elipsy.cpp \
grafy.cpp \
integrace.cpp
HEADERS += gui.h \
buffer.h \
qcustomplot.h
FORMS += gui.ui
And the error code it gives me when i try to compile with the function elipsy_button_clicked() in file other than gui.cpp
moc_gui.obj:-1: Chyba:LNK2019: unresolved external symbol "private: void __cdecl GUI::on_elipsy_button_clicked(void)" (?on_elipsy_button_clicked#GUI##AEAAXXZ) referenced in function "private: static void __cdecl GUI::qt_static_metacall(class QObject *,enum QMetaObject::Call,int,void * *)" (?qt_static_metacall#GUI##CAXPEAVQObject##W4Call#QMetaObject##HPEAPEAX#Z)
debug\GUI.exe:-1: Chyba:LNK1120: 1 unresolved externals
Well, in case you need the entire sourcecode, I uploaded it
http://seed.gweana.eu/public/GUI.7z
FIXED: The file was ignored by the project, running qmake again solved the issue. Many thanks for the answers :)
One of the problems is that you exported the slot methods to elipsy.cpp where on line 14 you try to use: ui ... which is defined in ui_gui.h included only in gui.cpp, but forward declared in gui.h (which you include of course in elipsy.cpp) so this should give you a compilation error. Solution: include ui_gui.h in elipsy.cpp. If it doesn't give you a compilation error try to rebuild the application.
Secondly, your drand function is defined in gui.cpp but not in any header file (easily fixable, modify gui.h)...
After fixing these two issues the compilation was ok for me.
So, a few recommendations:
Leave the things as they are when comes to Qt ... you will just mess up your head when moving things around.
have a separate "module" for utilities, such as drand
(PS: Nice app :) )
Generally slots are declared in a header file like,in my Counter.h :
#include <QObject>
class Counter : public QObject
{
Q_OBJECT
public:
Counter() { m_value = 0; }
int value() const { return m_value; }
public slots:
void setValue(int value);
....
Now in Counter.cpp(and it has to include Counter.h), i will define this function like any other normal function.
So in this case everything will work correctly.Does that answers your question?
Can anyone explain this error to me? It seems as though it is an error occurring with moc:
Undefined symbols:
make: Leaving directory `/Users/Dylan/Documents/programming/qt/Clock-build-desktop'
"ClockDelegate::ClockDelegate(QObject*)", referenced from:
AnalogClockDelegate::AnalogClockDelegate(QObject*)in AnalogClockDelegate.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
make: *** [Clock.app/Contents/MacOS/Clock] Error 1
The process "/usr/bin/make" exited with code 2.
Error while building project Clock (target: Desktop)
When executing build step 'Make'
ClockDelegate:
#ifndef CLOCKDELEGATE_H
#define CLOCKDELEGATE_H
#include <QObject>
class QTime;
class QWidget;
class ClockDelegate : public QObject
{
Q_OBJECT
public:
explicit ClockDelegate(QObject *parent);
virtual void paintClock(QWidget *, QTime *) = 0;
};
#endif // CLOCKDELEGATE_H
AnalogClockDelegate:
#ifndef ANALOGCLOCKDELEGATE_H
#define ANALOGCLOCKDELEGATE_H
#include <QColor>
#include <QPoint>
#include "ClockDelegate.h"
class QWidget;
class AnalogClockDelegate : public ClockDelegate
{
Q_OBJECT
public:
explicit AnalogClockDelegate(QObject *parent);
void paintClock(QWidget *, QTime *);
private:
void setupClockHands();
void drawClockSurface(QWidget *clockView, QTime *);
void drawHourComponent(QWidget *clockView);
void drawMinuteComponent(QWidget *clockView, QTime *);
void drawSecondComponent(QWidget *clockView, QTime *);
QPoint m_center;
QPoint m_hourHand[3];
QPoint m_minuteHand[3];
QPoint m_secondHand[2];
QColor m_hourColor;
QColor m_minuteColor;
QColor m_secondColor;
QColor m_clockFaceColor;
};
#endif // ANALOGCLOCKDELEGATE_H
I think you're missing the "public" keyword, assuming ClockDelegate is a QObject. Otherwise you're not derived from a QObject so you cannot use Q_OBJECT.
class AnalogClockDelegate : public ClockDelegate
I am coding a project. I started to getting errors after I tried to make the static build. I made some changes, which I can't remember. But, I am sure that if this stub can be cleared, then the main project also can be get cleared.
This is header file.
#ifndef MYLABEL_H
#define MYLABEL_H
#include <QFileDialog>
#include <QLabel>
#include <QMouseEvent>
#include <QObject>
#include <QPaintEvent>
class MyLabel:public QWidget
{
private:
QPixmap default_Pixmap;
QPixmap pixmap;
QFileDialog * fileDialog;
Q_OBJECT
public:
MyLabel();
void setPixmap(QPixmap pixmap);
void setDefault();
protected:
void mousePressEvent(QMouseEvent *event);
void paintEvent(QPaintEvent * event);
signals:
void file_Selected(QString fileName);
private slots:
void file_Got_Selected(QString fileName);
};
#endif // MYLABEL_H
Here is the source file
#include "MyLabel.h"
#include "MyMessageBox.h"
#include <QFileDialog>
#include <QPainter>
MyLabel::MyLabel():QWidget()
{
default_Pixmap = QPixmap("select.gif").scaled(250,100);
this->fileDialog=new QFileDialog(this);
fileDialog->setNameFilter("Image Files (*.BMP *.GIF *.JPG *.JPEG *.PNG *.PBM *.PGM *.PPM *.XBM *.XPM)");
connect(fileDialog,SIGNAL(fileSelected(QString)),this,SIGNAL(file_Selected(QString)));
connect(fileDialog,SIGNAL(fileSelected(QString)),this,SLOT(file_Got_Selected(QString)));
}
void MyLabel::setPixmap(QPixmap pixmap)
{
this->pixmap = pixmap;
}
void MyLabel::setDefault()
{
this->pixmap = default_Pixmap;
}
void MyLabel::mousePressEvent(QMouseEvent *event)
{
fileDialog->show();
//QString file_Name = file_Dialog.getOpenFileName();
}
void MyLabel::paintEvent(QPaintEvent * event)
{
QPainter painter(this);
painter.drawPixmap(0,0,width(),height(),pixmap.scaled(QSize(width(),height())));
}
void MyLabel::file_Got_Selected(QString fileName)
{
this->pixmap = QPixmap(fileName);
}
#include "myLabel.moc"
And this is the main file
#include <QLabel>
#include <QPixmap>
#include <QtGui/QApplication>
#include "myLabel.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MyLabel mm;
//mm.setPixmap(QPixmap("dummy.jpg"));
//mm.setPixmap(QPixmap());
mm.setDefault();
mm.show();
return a.exec();
}
I created the moc file using qt command prompt and the command
moc myLabel.h -o myLabel.moc
After this I tried to compile the project through Qt-Editor. But I got multi definition error as follows,
debug/moc_myLabel.o:d:/TempInstallationFolder/Qt/Dynamic/qt/include/QtCore/../../src/corelib/global/qglobal.h:1381: multiple definition of `MyLabel::metaObject() const'
debug/myLabel.o:C:\Documents and Settings\prabhakaran\Desktop\CalendarNew-build-desktop/../CalendarNew//myLabel.moc:57: first defined here
debug/moc_myLabel.o:C:\Documents and Settings\prabhakaran\Desktop\CalendarNew-build-desktop/debug/moc_myLabel.cpp:62: multiple definition of `MyLabel::qt_metacast(char const*)'
debug/myLabel.o:C:\Documents and Settings\prabhakaran\Desktop\CalendarNew-build-desktop/../CalendarNew//myLabel.moc:62: first defined here
debug/moc_myLabel.o:C:\Documents and Settings\prabhakaran\Desktop\CalendarNew-build-desktop/debug/moc_myLabel.cpp:70: multiple definition of `MyLabel::qt_metacall(QMetaObject::Call, int, void**)'
debug/myLabel.o:C:\Documents and Settings\prabhakaran\Desktop\CalendarNew-build-desktop/../CalendarNew//myLabel.moc:70: first defined here
debug/moc_myLabel.o:C:\Documents and Settings\prabhakaran\Desktop\CalendarNew-build-desktop/debug/moc_myLabel.cpp:87: multiple definition of `MyLabel::file_Selected(QString)'
debug/myLabel.o:C:\Documents and Settings\prabhakaran\Desktop\CalendarNew-build-desktop/../CalendarNew//myLabel.moc:87: first defined here
debug/moc_myLabel.o:moc_myLabel.cpp:(.data+0x0): multiple definition of `MyLabel::staticMetaObject'
debug/myLabel.o:myLabel.cpp:(.data+0x0): first defined here
collect2: ld returned 1 exit status
mingw32-make[1]: * [debug\CalendarNew.exe] Error 1
mingw32-make: * [debug] Error 2
The process "D:/TempInstallationFolder/Qt/Dynamic/mingw/bin/mingw32-make.exe" exited with code %2.
Error while building project CalendarNew (target: Desktop)
When executing build step 'Make'
Anybody please hep me out of this problem.
Try to remove line include "MyLabel.moc" form you source file. You don't need to include it into cpp file.