How to solve the multiple definition in Qt? - c++

I donĀ“t know why I got this problem, the header files are just included once but it continuous showing the error, I also already check the .pro file and every SOURCE is just included once. How can I solve this?
I will attach the files I'm using and their include and the code of the little ones
globals.h
#ifndef GLOBALS_H
#define GLOBALS_H
#include <QtGlobal>
#include "structs.h"
QT_BEGIN_NAMESPACE
struct ListaPaquetes;
QT_END_NAMESPACE
extern ListaPaquetes *nuevoPaquete;
#endif // GLOBALS_H
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QtGui>
#include <QDialog>
#include <QtCore>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_startButton_clicked();
void on_planificarProduButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
produccion.h (only the first lines)
#ifndef PRODUCCION_H
#define PRODUCCION_H
#include <QDialog>
structs.h (onyl first lines)
Here is the struct ListaPaquetes, which is the responsible of the error, so the problem I guess is with this file but I don't know why
#ifndef STRUCT_H
#define STRUCT_H
#include <QString>
#include <QList>
struct Nodo
{
int cantidad;
QString tipoPaquete;
Nodo *siguiente;
Nodo *anterior;
Nodo(){}
Nodo (int cant, QString paquete)
{
cantidad = cant;
tipoPaquete = paquete;
siguiente = nullptr;
anterior = nullptr;
}
};
struct ListaPaquetes
{
Nodo *pn;
ListaPaquetes()
{
pn = nullptr;
}
void crearPaquete(int,QString);
QList<QString> paquetesAgregados();
};
void ListaPaquetes::crearPaquete(int cant, QString paquete)
{
if (pn==nullptr)
{
pn = new Nodo(cant, paquete);
pn->siguiente = pn;
pn->anterior = pn;
}
else
{
Nodo *nuevo = new Nodo(cant, paquete);
pn->anterior->siguiente=nuevo;
nuevo->anterior = pn->anterior;
nuevo->siguiente=pn;
pn->anterior = nuevo;
}
}
QList<QString> ListaPaquetes::paquetesAgregados()
{
QList <QString> paquetes;
if (pn!=nullptr)
{
Nodo *tmp = pn;
do
{
paquetes.append(tmp->tipoPaquete);
tmp = tmp->siguiente;
}while(tmp!=pn);
}
return paquetes;
}
#endif // STRUCT_H
globals.cpp
#include "globals.h"
ListaPaquetes *nuevoPaquete = new ListaPaquetes();
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QColor>
#include <QColormap>
#include <QtCore>
#include <QtGui>
#include <QMessageBox>
#include "produccion.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_startButton_clicked()
{
if(ui->cantGalletas->text() == "")
{
QMessageBox::warning(this,"Error","Debe introducir una cantidad de
galletas");
}
}
void MainWindow::on_planificarProduButton_clicked()
{
Produccion *ventanaPaquetes = new Produccion();
ventanaPaquetes->show();
}
produccion.cpp (When I run something from here, it shows the error)
#include "produccion.h"
#include "ui_produccion.h"
#include <QtCore>
#include <QMessageBox>
#include "globals.h"
Here are the errors:

You are getting the problem because you are putting the implementation of member functions in header files (here structs.h). Every source file that includes globals.h will include structs.h and compile the functions implemented there. When you link your program these functions are multiply defined
You need to move ListaPaquetes::crearPaquete(int cant, QString paquete) and
ListaPaquetes::crearPaquete(int cant, QString paquete) into structs.cpp

Related

Inheritance from MainWindow problem in Qt

I wrote a program to control device with serial port. It works fine but I'd like to seperate the class which would operate serial ports. I also want to have acess to buttons, comboboxes, etc. from this class.
Here are most important parts of code:
Serialsettings header:
#ifndef SERIALSETTINGS_H
#define SERIALSETTINGS_H
#include <QMainWindow>
#include <QSerialPort>
#include "mainwindow.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class SerialSettings : public MainWindow
{
Q_OBJECT
public:
struct Settings
{
QString name;
qint32 baudRate;
QString stringBaudRate;
QSerialPort::DataBits dataBits;
QString stringDataBits;
QSerialPort::Parity parity;
QString stringParity;
QSerialPort::StopBits stopBits;
QString stringStopBits;
QSerialPort::FlowControl flowControl;
QString stringFlowControl;
};
explicit SerialSettings(QWidget *parent = nullptr);
~SerialSettings();
Settings settings() const;
signals:
private:
void fillPortsInfo();
void fillPortsParameters();
void updateSettings();
private:
Settings m_currentSettings;
};
#endif
Serialsettings source:
#include "serialsettings.h"
#include <QSerialPort>
#include <QSerialPortInfo>
#include "mainwindow.h"
#include "ui_mainwindow.h"
SerialSettings::SerialSettings(QWidget *parent)
: MainWindow(parent)
{
//some functions
}
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QSerialPort>
//#include "serialsettings.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class SerialSettings;
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
Ui::MainWindow *ui;
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
// some code
};
#endif
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "serialsettings.h"
#include <QSerialPortInfo>
#include <QSerialPort>
#include <QString>
#include <QDebug>
#include <QTimer>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//some code
};
MainWindow::~MainWindow()
{
delete ui;
}
I don't have any error at this moment but it finishes with: The program has unexpectedly finished.
Could you help me please with this problem?

QTCreator extern not working on specific PC

Hi I am currently working on a tournament creator program using QT Creator. I have been working on it at work during my lunch breaks and it has ran fine, but I have brought it home to get it finished for this weekend and it doesnt work.
The error which I am getting is
F:\Documents\Coding\TournamentOrganiser\startscreen.cpp:-1: error: multiple
definition of `StartScreen::StartScreen(QWidget*)'
I have literally only taken the folder placed it on a USB, copied it onto my desktop and ran it and this occurs, when it worked fine at home.
I assume that it is some kind of QT Creator configuration setting but just in case these are the files which are involved in the issue. If anyone can help me out with this it would be much appreciated as I need this working on my desktop for Saturday when I will need to use the app.
template <typename T> using shp = std::shared_ptr<T>;
globals.h
#ifndef GLOBALS_H
#define GLOBALS_H
#include "startscreen.h"
#include "tournamentcreator.h"
#include "player.h"
#include <memory>
#include "util.h"
#include "matchups.h"
namespace globals{
extern shp<StartScreen> g_StartScreen;
extern shp<TournamentCreator> g_TournamentCreator;
extern shp<std::vector<Player>> g_PlayerData;
extern shp<MatchUps> g_MatchUps;
}
#endif // GLOBALS_H
main.cpp
#include "startscreen.h"
#include "tournamentcreator.h"
#include "matchups.h"
#include <QApplication>
#include "util.h"
namespace globals{
shp<StartScreen> g_StartScreen;
shp<TournamentCreator> g_TournamentCreator;
shp<std::vector<Player>> g_PlayerData;
shp<MatchUps> g_MatchUps;
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
globals::g_StartScreen = std::make_shared<StartScreen>();
globals::g_TournamentCreator = std::make_shared<TournamentCreator>();
globals::g_PlayerData = std::make_shared<std::vector<Player>>();
globals::g_MatchUps = std::make_shared<MatchUps>();
globals::g_StartScreen->show();
return a.exec();
}
startscreen.h
#ifndef STARTSCREEN_H
#define STARTSCREEN_H
#include <QWidget>
namespace Ui {
class StartScreen;
}
class StartScreen : public QWidget
{
Q_OBJECT
public:
explicit StartScreen(QWidget *parent = 0);
~StartScreen();
private slots:
void on_newEventButton_clicked();
private:
Ui::StartScreen *ui;
};
#endif // STARTSCREEN_H
startscreen.cpp
#include "startscreen.h"
#include "ui_startscreen.h"
#include "globals.h"
StartScreen::StartScreen(QWidget *parent) :
QWidget(parent),
ui(new Ui::StartScreen)
{
ui->setupUi(this);
}
StartScreen::~StartScreen()
{
delete ui;
}
void StartScreen::on_newEventButton_clicked(){
this->hide();
globals::g_TournamentCreator->show();
}

How to connect a button from ui-file class to slots from other classes?

I have 3 classes.
class with a mainwindow which comes from the designer(ui-file)
class wich will manage database stuff like inserts
controller class. I want to extend the whole thing to networkcommunication later.
My problem:
I want to connect a simple QPushButton ui->addbutton from the window class with a slot addEntry from the databaseclass, but I get this error :
ERROR: no matching function for call to
'generalControler::connect(QPushButton*, const char*, dbmanager*&,
const char*)'
mydb, SLOT(addEntry()));
//no difference with &mydb or *mydb
MainWindow(0x13f57988, name = "MainWindow") QPushButton(0x13f5f3e0, name = "addButton")
MainWindow(0x13f57988, name = "MainWindow") 0x13f5f3e0//<--?????
//<=Here u see the adresses printed with Qdebug(). top: mainwindowclass. bot: generalcontrolerclass
//why there is missing information after returning the adress of a 'ui->addButton' to another class? Is this maybe the problem?
main.cpp
#include <QApplication>
#include "generalcontroler.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
generalControler controler;
return a.exec();
}
generalcontroler.h
#ifndef GENERALCONTROLER_H
#define GENERALCONTROLER_H
#include <QApplication>
#include "mainwindow.h"
#include "dbmanager.h"
class generalControler : public QObject
{
Q_OBJECT
public:
generalControler();
};
#endif // GENERALCONTROLER_H
generalcontroler.cpp
#include "generalcontroler.h"
#include <QDebug>
generalControler::generalControler(){
MainWindow* window = new MainWindow;
window->show();
dbmanager* mydb= new dbmanager("path_to_my_database.db", window);
mydb->addEntry();
qDebug()<<window->getThis()<<window->getcloseButton();
connect(window->getaddButton(), SIGNAL(clicked()),
mydb, SLOT(addEntry()));
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QMessageBox>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
QPushButton* getaddButton();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow){
ui->setupUi(this);
}
QPushButton* MainWindow::getaddButton()
{
return ui->addButton;
}
dbmanager.h
#ifndef DBMANAGER_H
#define DBMANAGER_H
#include <QSqlDatabase>
#include <QDebug>
#include "mainwindow.h"
class dbmanager: public QObject{
Q_OBJECT
public:
dbmanager(const QString& path);
public slots:
void addEntry();
private:
QSqlDatabase mydatabase;
};
#endif // DBMANAGER_H
dbmanager.cpp
#include "dbmanager.h"
dbmanager::dbmanager(const QString& path)
{
mydatabase = QSqlDatabase::addDatabase("QSQLITE");
mydatabase.setDatabaseName(path);
if (!mydatabase.open())
{
qDebug() << "Error: connection fail";
}
else
{
qDebug() << "Database: connection ok";
}
}
void dbmanager::addEntry()
{
qDebug()<<"addEntry success";
}
I was searching for 6 hours but I never saw such an example with 2 classes, a controler and an ui-file. Could anyone help me?
The connect looks good to me. Try if #include <QPushButton> in generalcontroler.cpp helps. If the compiler knows about QPushButton only by forward-declaration, it doesn't know that it's a QObject and thus the connect() signatures (with QObject* in it) don't match.

QT connect crash using signal accepted

I have a problem with my Qt code. I wanted to write an program which are taking a coordinates of point and then that point is drawing in point with that coordinates. My program doesn't have any errors or warnings when i built it but it's crashing at start(MainWindow doesn't show). This is my code:
main.cpp
#include < QApplication >
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow win;
win.show();
return app.exec();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QWidget>
#include <QAction>
#include <QToolBar>
#include <QTextCodec>
#include <QObject>
#include <QDialog>
#include <QLineEdit>
#include <QPushButton>
#include <QString>
#include "addpoint.h"
class MainWindow: public QMainWindow
{
Q_OBJECT
private:
QToolBar *AddToolbar;
QAction *AddPointAction;
AddPoint *AddPointDialog;
QLineEdit *x;
public:
MainWindow();
void createToolbar();
void createActionAdd();
signals:
public slots:
void PointClicked();
void DialogAccepted();
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
MainWindow::MainWindow()
{
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
createActionAdd();
createToolbar();
connect(AddPointAction, SIGNAL(triggered(bool)), this, SLOT(PointClicked()));
connect(AddPointDialog, SIGNAL(accepted()), this, SLOT(DialogAccepted()));
setMinimumSize(480, 320);
}
/**/
void MainWindow::createToolbar()
{
AddToolbar = new QToolBar;
AddToolbar->addAction(AddPointAction);
addToolBar(AddToolbar);
}
/**/
void MainWindow::createActionAdd()
{
AddPointAction = new QAction("Add Road", this);
x = new QLineEdit(this);
x->setFixedSize(100, 30);
x->move(100, 100);
}
/**/
void MainWindow::PointClicked()
{
AddPointDialog = new AddPoint(this);
AddPointDialog->setModal(true);
AddPointDialog->exec();
}
/**/
void MainWindow::DialogAccepted()
{
x->setText("abc");
}
addpoint.h
#ifndef ADDPOINT_H
#define ADDPOINT_H
#include <QWidget>
#include <QTextCodec>
#include <QDialog>
#include <QObject>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QString>
class AddPoint : public QDialog
{
Q_OBJECT
private:
QLabel *XpointL;
QLineEdit *XPoint;
QPushButton *OKButton;
public:
AddPoint(QWidget *parent);
void createButton();
signals:
public slots:
};
#endif // ADDPOINT_H
addpoint.cpp
#include "addpoint.h"
AddPoint::AddPoint(QWidget *parent) :QDialog(parent)
{
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
createButton();
connect(OKButton, SIGNAL(clicked(bool)), this, SLOT(accept()));
setMinimumSize(320, 240);
}
/**/
void AddPoint::createButton()
{
XpointL = new QLabel("Point X:", this);
XpointL->setFixedSize(100, 30);
XpointL->move(10, 10);
XPoint = new QLineEdit(this);
XPoint->setFixedSize(180, 30);
XPoint->move(120, 10);
OKButton = new QPushButton("OK", this);
OKButton->setFixedSize(100, 30);
OKButton->move(200, 150);
}
After running the program i see in aplication output lap:
"The program has unexpectedly finished."
"C:\QT\build-xxx-Desktop_Qt_5_4_2_MSVC2013_64bit-Debug\debug\xx.exe crashed"
I note that i made some experiments with this code and i saw that i have problem with signal accpeted() at mainwindow.cpp. I don't know what can i do with this problem. I hope you will help me.
AddPointDialog is uninitialized pointer, it does not yet point to valid AddPoint in MainWindow's constructor. You cannot call connect on that. Its value will change later, when you do AddPointDialog = new AddPoint(this); and only then will you be able to call connect.
Simply, you should move your connect call to void MainWindow::PointClicked() after you've initialized your pointer. I'd also make AddPointDialog local to that function and store it on the stack (you don't use it anywhere else and you're leaking memory).
The code would be:
void MainWindow::PointClicked()
{
AddPoint AddPointDialog(this);
AddPointDialog.setModal(true);
connect(&AddPointDialog, SIGNAL(accepted()), this, SLOT(DialogAccepted()));
AddPointDialog.exec();
}

Qt C++ - Can't add slots

When I add slots to my script it will no longer build.
inkpuppet.obj:-1: error: LNK2005: "private: void __cdecl InkPuppet::on_aboutButton_clicked(void)" (?on_aboutButton_clicked#InkPuppet##AEAAXXZ) already defined in main.obj
and
debug\InkPuppet.exe:-1: error: LNK1169: one or more multiply defined symbols found
Here is the code:
inkpuppet.h - commenting out void on_aboutButton_clicked(); and the function at the end will make it run.
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QtCore>
namespace Ui {
class InkPuppet;
}
class InkPuppet : public QWidget
{
Q_OBJECT
public:
explicit InkPuppet(QWidget *parent = 0);
~InkPuppet();
private:
Ui::InkPuppet *ui;
private slots:
void on_aboutButton_clicked();
};
#endif // WIDGET_H
void InkPuppet::on_aboutButton_clicked()
{
}
inkpuppet.cpp
#include "inkpuppet.h"
#include "ui_inkpuppet.h"
InkPuppet::InkPuppet(QWidget *parent) :
QWidget(parent),
ui(new Ui::InkPuppet)
{
ui->setupUi(this);
//connect(ui->lowerFrameBox, SIGNAL(valueChanged(int)), ui->timeSlider, SLOT(setRange(int,int)));
}
InkPuppet::~InkPuppet()
{
delete ui;
}
main.cpp
#include "inkpuppet.h"
#include "aboutdialog.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
InkPuppet w;
w.show();
return a.exec();
}
aboutdialog.h
#ifndef ABOUTDIALOG_H
#define ABOUTDIALOG_H
#include <QDialog>
namespace Ui {
class AboutDialog;
}
class AboutDialog : public QDialog
{
Q_OBJECT
public:
explicit AboutDialog(QWidget *parent = 0);
~AboutDialog();
private:
Ui::AboutDialog *ui;
};
#endif // ABOUTDIALOG_H
aboutdialog.cpp
#include "aboutdialog.h"
#include "ui_aboutdialog.h"
AboutDialog::AboutDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::AboutDialog)
{
ui->setupUi(this);
}
AboutDialog::~AboutDialog()
{
delete ui;
}
You define your void InkPuppet::on_aboutButton_clicked() in your inkpuppet.h. And then you include it in inkpuppet.cpp AND in main.cpp -> one or more multiply defined symbols found.
Put
void InkPuppet::on_aboutButton_clicked()
{
}
in your inkpuppet.cpp file.
If the first file you pasted is a whole, there's a problem with the include guards. The definition is after the guard's end.
#endif // WIDGET_H
void InkPuppet::on_aboutButton_clicked()
{
}
Your definition is right after the #endif which means as soon as in the same translation unit, the header is included twice, you'll get this error. And this happens in your code because inkpuppet.h is included in both main.cpp and in inkpuppet.cpp You should put the implementation code for on_aboutButton_clicked() in your inkpuppet.cpp file.