Unresolved external symbol on signals - c++

I was trying to make QLCDNumber clickable, by inheriting a new class from it. All it does is define a mouseReleaseEvent(QMouseEvent *e) sending a clicked() signal.
I think my code is correct, but it can't find the signal (unresolved external symbol on clicked() inside mouseReleaseEvent()
//myLCDNumber.h
#ifndef MYLCDNUMBER_H
#define MYLCDNUMBER_H
#include <QLCDNumber>
#include <QMouseEvent>
class myLCDNumber : public QLCDNumber
{
public:
myLCDNumber(uint numDigits);
~myLCDNumber();
void mouseReleaseEvent(QMouseEvent *e);
signals:
void clicked(void);
};
#endif // MYLCDNUMBER_H
//myLCDNumber.cpp
#include "mylcdnumber.h"
myLCDNumber::myLCDNumber(uint numDigits):QLCDNumber(numDigits){}
myLCDNumber::~myLCDNumber(){}
void myLCDNumber::mouseReleaseEvent(QMouseEvent *e)
{
qDebug("Click check");
if (e->button() == Qt::LeftButton)
emit myLCDNumber::clicked();
}
EDIT : I checked the SOURCES list for all my files to be correctly referenced in my project file, and I rerun qmake. No change.

Your problem is that you use signals and/or slots without using Qt's Meta Object Compiler. Add the Q_OBJECT Macro to your class definition and it'll work:
//myLCDNumber.h
#ifndef MYLCDNUMBER_H
#define MYLCDNUMBER_H
#include <QLCDNumber>
#include <QMouseEvent>
class myLCDNumber : public QLCDNumber
{
Q_OBJECT
public:
myLCDNumber(uint numDigits);
~myLCDNumber();
void mouseReleaseEvent(QMouseEvent *e);
signals:
void clicked(void);
};
#endif // MYLCDNUMBER_H
Don't forget to add the header file to the HEADERS variable and rerun qmake before building again.

You need to add Q_OBJECT macro to your class declaration and run qmake...maybe to rebuild your project

Related

C++ Qt4.8 :: Pass Object to another Class - member access into incomplete type error

I am new in C++ Qt and struggling with the correct use of forward declarations and #include.
What I want to do:
I have a Qt Gui (Class Ui::Gui) where we can set values.
I want to save these values in Gui Class variables.
As soon as a button (Generate Xml) is clicked, I want to pass the object
'ui' to the XmlGeneratorClass, So i can use the values to generate a Xml.
gui.h
#ifndef GUI_H
#define GUI_H
#include <QMainWindow>
#include <QDebug>
#include "xmlgeneratorqobject.h"
namespace Ui {
class Gui;
}
class Gui : public QMainWindow
{
Q_OBJECT
public:
explicit Gui(QWidget *parent = nullptr);
~Gui();
qint8 testvalue = 1;
signals:
void transmitToXmlGen(Ui::Gui*);
private slots:
void on_pushButtonGenerateXml_clicked();
private:
Ui::Gui *ui;
XmlGeneratorQObject *xmlgenerator = new XmlGeneratorQObject();
};
#endif // GUI_H
gui.cpp
#include "gui.h"
#include "ui_gui.h"
Gui::Gui(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Gui)
{
ui->setupUi(this);
connect(this,SIGNAL(transmitToXmlGen(Ui::Gui*)),xmlgenerator,SLOT(receiveFromGui(Ui::Gui*)));
}
Gui::~Gui()
{
delete ui;
}
void Gui::on_pushButtonGenerateXml_clicked()
{
emit transmitToXmlGen(ui);
}
xmlgeneratorqobject.h
#ifndef XMLGENERATORQOBJECT_H
#define XMLGENERATORQOBJECT_H
#include <QObject>
#include <QDebug>
namespace Ui {
class XmlGeneratorQObject;
class Gui;
}
class XmlGeneratorQObject : public QObject {
Q_OBJECT
public:
explicit XmlGeneratorQObject(QObject * parent = nullptr);
private slots:
void receiveFromGui(Ui::Gui*);
};
#endif // XMLGENERATORQOBJECT_H
xmlgeneratorqobject.cpp
#include "xmlgeneratorqobject.h"
XmlGeneratorQObject::XmlGeneratorQObject(QObject *parent){}
void XmlGeneratorQObject::receiveFromGui(Ui::Gui* objectFromGui)
{
qDebug() << objectFromGui->testvalue; // ERROR member access into incomplete type 'Ui::Gui'
}
Expected result:
Access to public variables from passed gui-object should be possible
Actual result:
member access into incomplete type 'Ui::Gui'
Can you please help me learn forward declaration / include?
Is my approach in general okay?
Your xmlgeneratorqobject.cpp needs the line
#include "ui_gui.h"
This gives it the details of the ui widgets. This file is generated by the Qt build system.

Use class A which includes class B from class B

I have four files:
mainwindow.h
#pragma once // MAINWINDOW_H
#include <QMainWindow>
#include <QApplication>
#include "maincontent.h"
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
void setStatusBarMessage(QString message);
signals:
public slots:
void exit();
private:
void setMenuBar();
MainContent* content;
};
maincontent.h
#pragma once // MAINCONTENT_H
#include "statistic.h"
#include "information.h"
#include <QWidget>
#include <QHBoxLayout>
class MainContent : public QWidget
{
Q_OBJECT
public:
explicit MainContent(QWidget *parent = nullptr);
signals:
public slots:
private:
QHBoxLayout* layout;
Statistic* statistic;
Information* financFlow;
};
information.h
#pragma once // INFORMATION_H
#include <QPushButton>
#include <QWidget>
//#include "mainwindow.h" //error
class Information : public QWidget
{
Q_OBJECT
public:
explicit Information(QWidget *parent = nullptr);
signals:
public slots:
private:
QPushButton* button;
};
statistic.h
#pragma once // STATISTIC_H
#include <QWidget>
#include <QHBoxLayout>
#include <QListView>
class Statistic : public QWidget
{
Q_OBJECT
public:
explicit Statistic(QWidget *parent = nullptr);
signals:
public slots:
private:
QListView* listView;
};
Now I will use the MainWindow::setStatusBarMessagemethod from the Information class.
But when I include the MainWindow in the Information class: #include "mainwindow.h"
I become the error: MainContent does not name a type in line 22 in mainwindow.h
First I don't know why the compiler can't find MainContent bacause in MainWindow I included the "maincontent.h", does the preprocessor only include "mainwindow.h" but not the "maincontent.h" in the "mainwindow.h"?
I see that with #include "mainwindow.h" a recursion arise but that shouldn't be a problem because of #pragma once or?
Next I tried to include the "mainwindow.h" in the information.cpp file but then I have the problem that I everytime give the MainWindow object by parameter and can't hold a MainWindow in my class
My main problem is that the MainWindow has a statusBar Object and I will set the statusBar message from everywhere. How can I do this, exist a Pattern or someting for that?
How can I solve this Problem or where I make a thinking mistake?
Thanks for your help.
You should use forward declaration for your included classes. Since pointers itself do not need to know a fully declared class (pointer size is always the same) you can easily get around this:
In header File instead of include the class just declare it:
#include <QMainWindow>
#include <QApplication>
//#include "maincontent.h" // REmove these
class MainContent;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
void setStatusBarMessage(QString message);
signals:
public slots:
void exit();
private:
void setMenuBar();
MainContent* content;
};
In cpp file now include the header again. Do this for all includes only having a pointer to given class.
As mentioned by #dempzorz removing the circular dependency is always prefered, but not always possible.
You have a circular dependency. You can't have information.h include mainwindow.h and also have mainwindow.h include information.h. You should design dependencies in a hierarchy, where items lower in the tree do not include items higher in the tree.
You should have a look at this link to maybe give you a better understanding of how to structure your objects:
https://en.wikipedia.org/wiki/Circular_dependency

Making custom QProgressBar

I'm getting the undefined reference to vtable for CustomProgressBar' error when trying to launch following code:
customprogressbar.h
#ifndef CUSTOMPROGRESSBAR_H
#define CUSTOMPROGRESSBAR_H
#include <QProgressBar>
#include "task.h"
class CustomProgressBar : public QProgressBar
{
Q_OBJECT
public:
CustomProgressBar(DayTask, QWidget* parent = 0);
protected:
void paintEvent(QPaintEvent *) Q_DECL_OVERRIDE;
private:
DayTask task;
};
#endif // CUSTOMPROGRESSBAR_H
customprogressbar.cpp
#include "customprogressbar.h"
#include <QPainter>
CustomProgressBar::CustomProgressBar(DayTask task, QWidget* parent) :
task{task},
QProgressBar(parent)
{
}
//paintevent
What could cause the problem?
Maybe moc (meta object compiler) is not being run for your header?
Anyway, it's duplicate for this question

Qt moving slots function to another cpp file

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?

Application crashes when declaring QPushButton in header

Currently using the latest QT Creator and working on a small tutorial application. Was wanting to have a button that all the function could use and placed it in the header file:
#ifndef GAMEBOARD_H
#define GAMEBOARD_H
#include <QWidget>
#include <QtGui/QPushButton>
class QLCDNumber;
class CannonField;
class QPushButton;
class Gameboard : public QWidget
{
Q_OBJECT
public:
Gameboard(QWidget *parent = 0);
private:
QLCDNumber *remaning_shots;
QLCDNumber *hits;
CannonField *cannon_field;
QPushButton *shootb;
public slots:
void shoot();
void hit();
void missed();
void restart();
};
#endif // GAMEBOARD_H
gameboard.cpp:
#include "cannonfield.h"
#include "gameboard.h"
#include "lcdrange.h"
Gameboard::Gameboard(QWidget *parent)
: QWidget(parent) {
shootb = new QPushButton(tr("Shoot"));
And when I'm trying to run the application it just crashes before it even begins. I don't even have to use the button for anything, it crashes anyway. What am I doing wrong?
Or should I just use signals?
QPushButton *shootb = new QPushButton(tr("Shoot"));
connect(this, SIGNAL(disableShoot(bool)), shootb, SLOT(setDisabled(bool)));
And then I call it like this:
void Gameboard::missed() {
emit disableShoot(true);
}
Correct me if that's an ugly solution.