Undefined struct 'addrinfo' winsock2 - c++

I encountered an error and I didn't find any solution (even over the internet)
I created aQt app to receive data using a TCP protocol and plot them using QcustomPlot.
I have the following files:
mainwindow.h :
#pragma once
#include <QtWidgets/QMainWindow>
#include "ui_mainwindow.h"
#include <QVector>
#include <iostream>
class MainWindow: public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = Q_NULLPTR);
// ...
private:
struct addrinfo _hints;
struct addrinfo* _result = NULL;
// ...
};
mainwindow.cpp :
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#pragma comment(lib, "ws2_32.lib")
#include "mainwindow.h"
#include <QVector>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
//...
}
and the main.cpp file:
#include "mainwindow.h"
#include <QtWidgets/QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
I have the following error:
'MainWindow::hints' uses undefined struct 'addrinfo' (compiling source file main.cpp).
I don't understand why I have this error, because I tested the same program in a classic consol app following the microsoft tutorial and it was working.
I believe it comes from the includes, but I still dont have a clue about which one causes that.

You need to #include something in your mainwindow.h that defines struct addrinfo, because your MainWindow class has a member variable of that type. At the moment you include all the socket stuff only in your *.cpp file.

You use #define WIN32_LEAN_AND_MEAN that prevents including many dependent header files and makes you include required header files explicitly. As for addrinfo you have to #include <ws2def.h>.

Related

Downloading txt file with qtnetwork

I am trying to download a txt file from a url in QT but i can't seem to make it work.
I am following this guide https://wiki.qt.io/Download_Data_from_URL. I implemented the filedownloader class exactly like it's made in the guide, but when i try to use it like specified in the guide I cannot make it work. I created a slot to be called when the download is finished, but if i try to call the downloader inside like the guide it says it is an undeclared identifier.
Does anyone know how to correctly implement this code?
this is the .cpp of my code
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "mainwindow.h"
#include <QStringList>
#include <QCoreApplication>
#include <QFile>
#include <QFileInfo>
#include <QList>
#include <QtNetwork/QNetworkReply>
#include <QStringList>
#include <QTimer>
#include <QUrl>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkRequest>
#include <filedownloader.h>
#include <iostream>
#include <QObject>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QUrl emiurl( "url of my file");
// call to the downloader class.In the guide it's made differently, but it doesn't work
FileDownloader emiload(emiurl,this);
//this connect links the end of the download with the textwriter slot
QObject::connect(&emiload, SIGNAL (downloaded()), this, SLOT (textwriter()));
}
>MainWindow::~MainWindow()
{
delete ui;
}
//slot needed to create the txt file from the downloaded one
void MainWindow::textwriter()
{
QByteArray emibyte;
emibyte=emiload->downloadedData(); //this line gives me error
QFile emifile("emi.txt");
emifile.open(QIODevice::WriteOnly);
std::cout << emibyte.size() << std::endl;
QDataStream out(&emifile);
out << emibyte;
std::cout << emifile.size() << std::endl;
}
Now here's the .h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "filedownloader.h"
#include <QMainWindow>
#include <QtNetwork/QNetworkAccessManager>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
private slots:
void textwriter();
};
#endif // MAINWINDOW_H
To make the undeclared identifier go away and successfully compile, you need to add FileDownloader to the class' declaration. This way, it will be known throughout the class.
I chose to go with the approach that's usual in Qt, to declare a pointer to FileDownloader.
#pragma once // <--- this is supported by virtually any compiler today
#include <QMainWindow>
#include <QtNetwork/QNetworkAccessManager>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class FileDownloader; // <-- forward declaration is enough, but you can also #include "filedownloader.h"
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget* parent = nullptr);
~MainWindow();
private:
Ui::MainWindow* ui = nullptr;
FileDownloader* emiload = nullptr; // <--- the important line!
private slots:
void textwriter();
};
And then instantiate and call emiload in the constructor:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// create an instance of FileDownloader with "new".
emiload = new FileDownloader(QUrl("url of my file"), this);
// using member pointer connection available since Qt5
connect(emiload, &FileDownloader::downloaded, this, &MainWindow::textwriter);
}

How to connect QObbject (QPushButton) to a method from other class?

I'm currently working on a project that need the connection between a QPushButton of a Qwidget class (window) and a void method from a "classical" class.
I've tried to connect them with all the solution that I've read but none works correctly.
Either the compiler returns me
QObject::connect: No such slot QWidget::Class::metoh()
or it won't compile at all without errors.
Here's the simpliest code that I've tried. I read the Qt documentation but it didn't help me. I've also tried to include the Q_OBJECT Macro but it lead to errors. I've also read that with Qt5 it's no more mandatory to define slots. Have I understood correctly ?
How can I connect the Some_Class method to the QPushButton ?
// Classical class header //
#ifndef DEF_CLASS
#define DEF_CLASS
#include <iostream>
#include <cstdlib>
#include <string>
class Some_class
{
protected: // permet l'acces pour les methodes style soin
Some attributes;
public:
Some_Class(int id);
//Personnage(int id, int vieAtStart, int degatsArmeAtStart);
void method();
// obligation de passer par des references pour avoir une modification effective
~Some_Class();
};
#endif
// Classical class cpp //
#include "Some_Class.h"
#include <QObject>
#include <iostream>
#include <cstdlib>
#include <string>
#include <vector>
using namespace std;
Some_Class::Some_Class(int id)
{
Id = id;
some attributes;
};
void Some_Class::method()
{
modification of attributes;
};
// Window class header //
#ifndef DEF_WINDOW
#define DEF_WINDOW
#include <QApplication>
#include <QWidget>
#include <QLabel>
#include <QPushButton>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QIcon>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QImage>
#include <QPixmap>
#include <QLabel>
#include <QGraphicsPixmapItem>
#include "Some_Class.h"
class Window : public QWidget // On hérite de QWidget (IMPORTANT)
{
public:
Window(Some_Class test);
// public slots:
// void go_right();
private:
QPushButton *m_button;
};
#endif
// Window class cpp //
#include "Window.h"
#include <string>
#include <QObject>
Window::Window(Some_Class test) : QWidget()
{
setFixedSize(874, 968);
m_button = new QPushButton("test", this);
QObject::connect(m_button, SIGNAL(clicked()), this, SLOT(Some_Class::method()));
//QObject::connect(m_bouton_droite, SIGNAL(clicked()), qApp, Personnage::go_right());
//QObject::connect(m_bouton_droite, &QPushButton::clicked,qApp, Personnage::go_right());
}
#include <QApplication>
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QLabel>
#include <QIcon>
#include "Window.h"
#include "Some_Class.h"
#include <QObject>
// main.cpp //
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Window win(Heros);
win.show();
return app.exec();
}
First, you will need an object of Some_Class with an appropriate scope. Currently you only have test in your constructor which is a value parameter and thus gets destroyed when the constructor returns. One option would be to pass in test as a pointer if the object you are passing in has the correct lifetime.
Window::Window(Some_Class *test)
If that is not appropriate in your case you will need to keep a copy inside your Window object. For the rest of this answer I will however assume you pass in a pointer.
With a normal C++ object (not a QObject) you cannot use the SIGNAL/SLOT macro's because they require the use of the slot/signal markers in the class definition.
I see you tried to use the modern method pointer syntax but you made one error. The third parameter needs to be the address of an object of type Some_Class.
QObject::connect(m_button, &QPushButton::clicked, test, &Some_Class::method);
However that is not all, for this to work the signature of clicked has to match with Some_Class::method which it doesn't. clicked has a bool checked parameter.
The construct with the SIGNAL/SLOT macro's allows the slot to have less parameters but this version of connect is more strict and requires a strict match.
You can either add the parameter to method or use a lambda if you have C++11.
QObject::connect(m_button, &QPushButton::clicked, [test] (bool) {
test->method();
});

How to solve the multiple definition in Qt?

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

How do I connect this function to my connectButton?

I am trying to connect the addDevice() function from my Device class to my connectButton on my GUI. However no matter how I try and code the connect function, it does not work. Currently it is giving me the error:
primary expression expected before the ',' token.
I have tried the follow syntaxes:
connect(ui->connectButton,SIGNAL(clicked(bool)),d,SLOT(startDeviceDiscovery()));
connect(ui->connectButton,SIGNAL(clicked(bool)),d,&Device::startDeviceDiscovery());
connect(ui->connectButton,SIGNAL(clicked(bool)),this,SLOT(startDeviceDiscovery()));
connect(ui->connectButton,SIGNAL(clicked(bool)),this,Device::startDeviceDiscovery());
MainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QObject>
#include <QBluetoothDeviceDiscoveryAgent>
#include <QtBluetooth>
#include <QDebug>
#include <QtWidgets>
#include "device.h"
#include "deviceinfo.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
Device d;
connect(ui->connectButton,SIGNAL(clicked(bool)),Device,SLOT(startDeviceDiscovery()));
//
.
.
.
}
Device.h
#ifndef DEVICE_H
#define DEVICE_H
#include <QObject>
#include <qbluetoothglobal.h>
#include <qbluetoothlocaldevice.h>
#include <QBluetoothDeviceDiscoveryAgent>
#include <QLowEnergyController>
#include <QBluetoothDeviceInfo>
#include <QBluetoothServiceInfo>
#include "deviceinfo.h"
#include <QList>
#include <QVariant>
class Device : public QObject
{
Q_OBJECT
public:
explicit Device(QObject *parent = 0);
QVariant name();
~Device();
signals:
void address(QVariant);
public slots:
void startDeviceDiscovery();
void connectDeivce(const QString &address);
};
#endif // DEVICE_H
For a connect you need a pointer, and you created your Device on the constructor, this means that just after the connect is used, constructor would finish, and this would destroy your device, disconnecting the function.
Correct syntax:
Device *myDevice = new Device();
connect(
ui->connectButton, // the pointer of the signal emitter
&QPushButton::clicked, // the signal you are interested
myDevice, // the pointer to receiving end
&Device::startDeviceDiscovery); // what you wanna trigger
you mixed every possibility in your tests, but in all of them you treated the slot as a method, calling the () operator. you can't call the call operator, on the connect you are passing the pointer of the method to a function that will call that for you when the time is right.

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();
}