Signals- Slots; emit one signal from one Form to multiple forms + mainwindow
Hello community,
i have one class called mInterface(mInterface.cpp + mInterface.h) that reads data from udpSocket and then send those data to mupltiple(2) Forms(.ui) and mainwindow. i use Signals and slots communication to emit the data to all another forms.
normally, when i start my project i have to read datagram from udpsocket and then directly emit received data to Forms of my projects. Reading of datagram runs fine but the transfer of data to other forms doesn't works well. Only one Form receives transmitted data and the ather not. all classes Form are written in the same way but i don't understand why only one Form receives transmitted signal(data).
according to the signals/slots communication we can emit one signal to more slots from multiple objects or Form(.ui). if yes, why my project not works? somebody have an idea?
in advance, thank you for your help.
//mInterface.cpp class
Code:
#include "minterface.h"
{
connect(readSocket, SIGNAL(readyRead()), this, SLOT(receiveData()));
}
void mInterface::receiveData()
{
do
{
rDatagram.resize(int(readSocket->pendingDatagramSize()));
readSocket->readDatagram(rDatagram.data(), rDatagram.size());
} while(readSocket->hasPendingDatagrams());
memccpy(&arrChannels, (const void *)rDatagram.data(), sizeof(arrChannels), sizeof(arrChannels));
//int nombre = qrand()%(101);
qDebug()<<"mInterface : "<<arrChannels[0].AC_Volt;
emit dataAllChannels(arrChannels[0].AC_Volt);
}
form1.cpp
Code:
#include "readform.h"
#include "ui_readform.h"
ReadForm
::ReadForm(QWidget *parent
) : ui(new Ui::ReadForm)
{
ui->setupUi(this);
connect(&interface, SIGNAL(dataAllChannels(float)), this, SLOT(setReadData(float)));
qDebug()<<"readform constructor";
}
ReadForm::~ReadForm()
{
delete ui;
}
void ReadForm::setReadData(float d)
{
qDebug()<<"readform : "<<d;
ui->lcdNumber->display(d);
}
void ReadForm::on_pushButton_clicked()
{
mform2.show();
}
form2.cpp
Code:
#include "form2.h"
#include "ui_form2.h"
ui(new Ui::Form2)
{
ui->setupUi(this);
connect(&form2, SIGNAL(dataAllChannels(float)), this, SLOT(meinSlot(float)));
qDebug()<<"readform2 constructor";
}
Form2::~Form2()
{
delete ui;
}
void Form2::meinSlot(float f2)
{
ui->lcdNumber->display(f2);
qDebug()<<"readform2 : "<< f2;
}
//mainwindow.cpp
Code:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow
::MainWindow(QWidget *parent
) : ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(&m, SIGNAL(dataAllChannels(float)), this, SLOT(readAllValue(float)));
qDebug()<<"Mainwindow constructor";
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::readAllValue(float c)
{
qDebug()<<"Read Mainwindow : "<<c;
ui->lcdNumber->display(c);
}
void MainWindow::on_pushButton_clicked()
{
readform.show();
}
//main.cpp
Code:
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
MainWindow w;
w.show();
return a.exec();
}
Re: Signals- Slots; emit one signal from one Form to multiple forms + mainwindow
At 99, (9)% error is on your side.
1. You did not say which form receives the signal and which is not.
2. You did not show h files.
Re: Signals- Slots; emit one signal from one Form to multiple forms + mainwindow
I agree with Lesiok. You need to show the -complete code- not just the part you think is important.
My guess is that in every one of the signal / slot connections you are making, you are using a different instance of your "mInterface" class. I say this because in each of the connect() statements, it looks like you are using the address of a member variable (&interface) instead of a pointer. That tells me you are probably creating that variable on the stack during the construction of your forms and are not passing in the address of the single mInterface instance that is the one receiving the data. Only the first instance created does anything, because after it has been bound to the read socket, the other calls to bind() fail (but you don't bother to check to see if the bind() was successful...).
Re: Signals- Slots; emit one signal from one Form to multiple forms + mainwindow
Thank you for your feedback,
Quote:
Lesiok
At 99, (9)% error is on your side.
1. You did not say which form receives the signal and which is not.
mainwindow, readform and form2 have to receive the signal. i can see that.
mInterface.h
Code:
#ifndef MINTERFACE_H
#define MINTERFACE_H
#include <QUdpSocket>
#include <QDataStream>
{
Q_OBJECT
public:
explicit mInterface
(QObject *parent
= nullptr
);
signals:
void dataAllChannels(double);
public slots:
void receiveData();
private:
};
#endif // MINTERFACE_H
readform.h
Code:
#ifndef READFORM_H
#define READFORM_H
#include <QWidget>
#include <minterface.h>
#include <QDebug>
namespace Ui {
class ReadForm;
}
{
Q_OBJECT
public:
explicit ReadForm
(QWidget *parent
= nullptr
);
~ReadForm();
private slots:
void setReadData(float);
private:
Ui::ReadForm *ui;
mInterface interface;
Form mform2;
};
#endif // READFORM_H
form2.h
Code:
#ifndef FORM2_H
#define FORM2_H
#include <QWidget>
#include <minterface.h>
#include <QDebug>
namespace Ui {
class Form2;
}
{
Q_OBJECT
public:
explicit Form2
(QWidget *parent
= nullptr
);
~Form2();
private slots:
void meinSlot(float);
private:
Ui::Form2 *ui;
mInterface form2;
};
#endif // FORM2_H
mainwindow.h
Code:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QDebug>
#include <minterface.h>
#include <readform.h>
namespace Ui {
class MainWindow;
}
{
Q_OBJECT
public:
explicit MainWindow
(QWidget *parent
= nullptr
);
~MainWindow();
public slots:
void readAllValue(floatc);
private slots:
void on_pushButton_clicked();
void on_pushStop_clicked();
private:
Ui::MainWindow *ui;
mInterface m;
ReadForm readform;
};
#endif // MAINWINDOW_H
Re: Signals- Slots; emit one signal from one Form to multiple forms + mainwindow
As I guessed:
class ReadForm has a member variable of type mInterface.
class Form2 has a member variable of type mInterface.
class MainWindow has a member variable of type mInterface.
When constructed, these become three completely independent instances of the mInterface class. Only one of them (whichever is constructed first - probably the one in the MainWindow instance constructed in main.cpp) will be successfully be bound to the socket and receive packets. For the other two, the call to bind() will fail because another instance got there first to bind the socket.
You need to rethink your design and consider how a single instance of a class can be shared among multiple other class instances. It isn't hard - I gave you a hint in my previous answer.
Re: Signals- Slots; emit one signal from one Form to multiple forms + mainwindow
Thank you for your contribution,
Quote:
Originally Posted by
d_stranz
I agree with Lesiok. You need to show the -complete code- not just the part you think is important.
My guess is that in every one of the signal / slot connections you are making, you are using a different instance of your "mInterface" class. I say this because in each of the connect() statements, it looks like you are using the address of a member variable (&interface) instead of a pointer. That tells me you are probably creating that variable on the stack during the construction of your forms and are not passing in the address of the single mInterface instance that is the one receiving the data. Only the first instance created does anything, because after it has been bound to the read socket, the other calls to bind() fail (but you don't bother to check to see if the bind() was successful...).
I think you are right. When I started the program found that the constructor of the class "mInterface" was called 3 times so 3 different instance of mInterface. once by calling the class Mainwindow + once by calling the class Readform and once by calling the class Form2. When i try with pointer by it is the same. I declared a pointer of mInterface in mainwindow, form2 and readForm for signals/slots-connection but nothing else happening only the same result.
How can i do that(to declare only one instance of mInterface )? can you give me a example?
thanks.
Added after 1 8 minutes:
Quote:
Originally Posted by
d_stranz
As I guessed:
class ReadForm has a member variable of type mInterface.
class Form2 has a member variable of type mInterface.
class MainWindow has a member variable of type mInterface.
When constructed, these become three completely independent instances of the mInterface class. Only one of them (whichever is constructed first - probably the one in the MainWindow instance constructed in main.cpp) will be successfully be bound to the socket and receive packets. For the other two, the call to bind() will fail because another instance got there first to bind the socket.
You need to rethink your design and consider how a single instance of a class can be shared among multiple other class instances. It isn't hard - I gave you a hint in my previous answer.
it runs very well. Thank you very much for your help.