PDA

View Full Version : how to pass param./pointer il call->connect(...., SLOT(func_to_call(Q.. *par_1, ecc)



andreaQt
4th April 2018, 09:52
I have built this program for catch the incoming message on UDP protocol, now my goal is to set/change the IP address/port by cliccking on a push button (es. Set_IP_PC_Button_1).
Using connect i want to call a function where i pass the pointer of the socket and the pointer of 2 Qtextedit (where is the IP and PORT value to change).
I post now the code of my file, i try to use lambda function to to this, but no solution that i've tried reach the goal.
//-----------------------------------------------------------------------------------------------------------------------------//
FILE -> receiver.h

#ifndef RECEIVER_H
#define RECEIVER_H
#include <QWidget>
#include <QTextEdit>

QT_BEGIN_NAMESPACE
class QLabel;
class QPushButton;
class QUdpSocket;
class QAction;
QT_END_NAMESPACE

class Receiver : public QWidget
{
Q_OBJECT

public:
Receiver(QWidget *parent = 0);

private slots:
void clearBroadcasting();

void processPendingDatagrams();
void processPendingDatagramsDisconnect();

void processPendingDatagrams2();
void processPendingDatagramsDisconnect2();

void change_IP_Pc_1(QUdpSocket *socket, QTextEdit *IP, QTextEdit *Port);
void change_IP_Pc_2(QUdpSocket *socket, QTextEdit *IP, QTextEdit *Port);


private:
QLabel *receiverFrom1;
QLabel *statusLabel1;

QLabel *receiverFrom2;
QLabel *statusLabel2;

QUdpSocket *udpSocket1;
QUdpSocket *udpSocket2;

QTextEdit *printscrolltext1;
QTextEdit *printscrolltext2;

QTextEdit *IP_Host_1;
QTextEdit *Port_Host_1;
QPushButton *Set_IP_PC_Button_1;

QTextEdit *IP_Host_2;
QTextEdit *Port_Host_2;
QPushButton *Set_IP_PC_Button_2;

QPushButton *quitButton;
QPushButton *clearButton;

};

#endif

//-----------------------------------------------------------------------------------------------------------------------------//
FILE -> receiver.cpp

#include <QtWidgets>
#include <QtNetwork>
#include "receiver.h"

#define HOST_PC_1_ADDRESS "101.101.101.101"
#define HOST_PC_1_PORT 5000

#define HOST_PC_2_ADDRESS "101.101.101.101"
#define HOST_PC_2_PORT 7500

//---------------------------------------------------------------------------------
Receiver::Receiver(QWidget *parent): QWidget(parent)
{
IP_Host_1 = new QTextEdit(tr(HOST_PC_1_ADDRESS));
IP_Host_1->setReadOnly(false);
IP_Host_1->setFixedSize(120,30);
Port_Host_1 = new QTextEdit(tr("5000"));
Port_Host_1->setFixedSize(120,30);
Port_Host_1->setReadOnly(false);

IP_Host_2 = new QTextEdit(tr(HOST_PC_2_ADDRESS));
IP_Host_2->setReadOnly(false);
IP_Host_2->setFixedSize(120,30);
Port_Host_2 = new QTextEdit(tr("7500"));
Port_Host_2->setFixedSize(120,30);
Port_Host_2->setReadOnly(false);

Set_IP_PC_Button_1 = new QPushButton(tr("&Set IP Pc + port '1'"));
Set_IP_PC_Button_2 = new QPushButton(tr("&Set IP Pc + port '2'"));

receiverFrom1 = new QLabel(tr("Recive from : Nothing"));
receiverFrom1->setWordWrap(true);
statusLabel1 = new QLabel(tr("Listening for broadcasted messages"));
statusLabel1->setWordWrap(true);

receiverFrom2 = new QLabel(tr("Recive from : Nothing"));
receiverFrom2->setWordWrap(true);
statusLabel2 = new QLabel(tr("Listening for broadcasted messages"));
statusLabel2->setWordWrap(true);

quitButton = new QPushButton(tr("&Quit"));
clearButton = new QPushButton(tr("&Clear"));
clearButton->setEnabled(false);

printscrolltext1 = new QTextEdit(tr(""));
printscrolltext1->setReadOnly(true);
printscrolltext2 = new QTextEdit(tr(""));
printscrolltext2->setReadOnly(true);

//! [0]
udpSocket1 = new QUdpSocket(this);
udpSocket2 = new QUdpSocket(this);
udpSocket1->bind(QHostAddress(HOST_PC_1_ADDRESS),HOST_PC_1_POR T);
udpSocket2->bind(QHostAddress(HOST_PC_2_ADDRESS),HOST_PC_2_POR T);
//! [0]

//! [1]
connect(udpSocket1, SIGNAL(readyRead()), this, SLOT(processPendingDatagrams()));
connect(udpSocket1, SIGNAL(disconnected()), this, SLOT(processPendingDatagramsDisconnect()));

connect(udpSocket2, SIGNAL(readyRead()), this, SLOT(processPendingDatagrams2()));
connect(udpSocket2, SIGNAL(disconnected()), this, SLOT(processPendingDatagramsDisconnect2()));

connect(quitButton, SIGNAL(clicked()), this, SLOT(close()));
connect(clearButton, SIGNAL(clicked()), this, SLOT(clearBroadcasting()));

connect(Set_IP_PC_Button_1, SIGNAL(clicked()), this, SLOT(change_IP_Pc_1(udpSocket1, IP_Host_1,Port_Host_1)));
connect(Set_IP_PC_Button_2, SIGNAL(clicked()), this, SLOT(change_IP_Pc_2(udpSocket2, IP_Host_2,Port_Host_2)));
//connect(Set_IP_PC_Button_1, SIGNAL(clicked()),this,SLOT(change_IP_Pc_1(QUdpSoc ket* ,QTextEdit* ,QTextEdit* )));
//connect(Set_IP_PC_Button_2, SIGNAL(clicked()),this,SLOT(change_IP_Pc_2(QUdpSoc ket* ,QTextEdit* ,QTextEdit* )));
//connect(Set_IP_PC_Button_1, SIGNAL(clicked()),[=](){Receiver::change_IP_Pc_1(udpSocket1, IP_Host_1,Port_Host_1);});
//connect(Set_IP_PC_Button_1, SIGNAL(clicked()),[=](){Receiver::change_IP_Pc_2(udpSocket2, IP_Host_2,Port_Host_2);});

/*
* example lambda fuction
connect( sender, &Sender::valueChanged, [=](){ myMethod(5); } );

void myMethod(int value)
{
// do stuff
}
*/

//! [1]

QHBoxLayout *buttonLayout = new QHBoxLayout;
buttonLayout->addStretch(1);
buttonLayout->addWidget(clearButton);
buttonLayout->addWidget(quitButton);
buttonLayout->addStretch(1);

QHBoxLayout *buttonLayout_1 = new QHBoxLayout;
buttonLayout_1->addStretch(1);
buttonLayout_1->addWidget(Set_IP_PC_Button_1);
buttonLayout_1->addStretch(1);

QHBoxLayout *buttonLayout_2 = new QHBoxLayout;
buttonLayout_2->addStretch(1);
buttonLayout_2->addWidget(Set_IP_PC_Button_2);
buttonLayout_2->addStretch(1);

QVBoxLayout *mainLayout = new QVBoxLayout;
mainLayout->addWidget(IP_Host_1);
mainLayout->addWidget(Port_Host_1);
mainLayout->addLayout(buttonLayout_1);
mainLayout->addWidget(receiverFrom1);
mainLayout->addWidget(statusLabel1);
mainLayout->addWidget(printscrolltext1);

mainLayout->addWidget(IP_Host_2);
mainLayout->addWidget(Port_Host_2);
mainLayout->addLayout(buttonLayout_2);
mainLayout->addWidget(receiverFrom2);
mainLayout->addWidget(statusLabel2);
mainLayout->addWidget(printscrolltext2);

mainLayout->addLayout(buttonLayout);

setLayout(mainLayout);

setWindowTitle(tr("Broadcast Receiver"));
}
//---------------------------------------------------------------------------------
void Receiver::clearBroadcasting()
{
printscrolltext1->clear();
printscrolltext2->clear();
clearButton->setEnabled(false);
}
//---------------------------------------------------------------------------------
void Receiver::processPendingDatagrams()
{
//! [2]
while (udpSocket1->hasPendingDatagrams()) {
receiverFrom1->setText(tr("Recive from IP: %1 - Port: %2")
.arg(udpSocket1->localAddress().toString())
.arg(udpSocket1->localPort())
);
QByteArray datagram;
QString test="Off Line";
datagram.resize(udpSocket1->pendingDatagramSize());
udpSocket1->readDatagram(datagram.data(), datagram.size());
statusLabel1->setText(tr("Received datagram: \"%1\"").arg(datagram.data()));
printscrolltext1->insertPlainText(tr("\%1\n").arg(datagram.data()));

if (QString(datagram.data()).contains(test, Qt::CaseInsensitive)){
clearButton->setEnabled(true);
}
}
//! [2]
}
//---------------------------------------------------------------------------------
void Receiver::processPendingDatagrams2()
{
//! [2]
while (udpSocket2->hasPendingDatagrams()) {
receiverFrom2->setText(tr("Recive from IP: %1 - Port: %2")
.arg(udpSocket2->localAddress().toString())
.arg(udpSocket2->localPort())
);
QByteArray datagram;
QString test="Off Line";
datagram.resize(udpSocket2->pendingDatagramSize());
udpSocket2->readDatagram(datagram.data(), datagram.size());
statusLabel2->setText(tr("Received datagram: \"%1\"").arg(datagram.data()));
printscrolltext2->insertPlainText(tr("\%1\n").arg(datagram.data()));

if (QString(datagram.data()).contains(test, Qt::CaseInsensitive)){
clearButton->setEnabled(true);
}
}
//! [2]
}
//---------------------------------------------------------------------------------
void Receiver::processPendingDatagramsDisconnect()
{
receiverFrom1->setText("Stopped");
clearButton->setEnabled(true);
}
//---------------------------------------------------------------------------------
void Receiver::processPendingDatagramsDisconnect2()
{
receiverFrom1->setText("Stopped");
clearButton->setEnabled(true);
}
//---------------------------------------------------------------------------------
void Receiver::change_IP_Pc_1(QUdpSocket *socket, QTextEdit *IP, QTextEdit *Port)
{
socket->bind(QHostAddress(IP->toPlainText()), Port->toPlainText().toInt());
}
//---------------------------------------------------------------------------------
void Receiver::change_IP_Pc_2(QUdpSocket *socket, QTextEdit *IP, QTextEdit *Port)
{
socket->bind(QHostAddress(IP->toPlainText()), Port->toPlainText().toInt());
}
//-----------------------------------------------------------------------------------------------------------------------------//

I have an other question, when i call the function change_IP_Pc_n i have to close & disconnect the previous bind or this is overwrite/rebuilt?
Note: I'm a beginner on programming.

d_stranz
4th April 2018, 15:53
Please, please use CODE tags when posting source code. See my signature below for one way to do this.



connect(Set_IP_PC_Button_1, SIGNAL(clicked()), this, SLOT(change_IP_Pc_1(udpSocket1, IP_Host_1,Port_Host_1)));
connect(Set_IP_PC_Button_2, SIGNAL(clicked()), this, SLOT(change_IP_Pc_2(udpSocket2, IP_Host_2,Port_Host_2)));


You misunderstand how signals and slots work. The method signature for a slot must match the method signature for the signal it is connected to. The signature for a pushbutton click is void QPushButton::clicked( void ). Therefore, any slot you connect to it must have the same signature:



private slots:
void Receiver::onButtonCLicked();


You can't just add arbitrary arguments to a slot method. How is a QPushButton instance supposed to know how to fill in the values of "udpSocket1", "IP_Host_1", and "Port_Host_1"? All it knows is that when someone clicks it, it emits the "clicked()" signal.

So add slots to your class to correctly handle the clicked() signal. In those slots, you can call the functions to set the port information.

andreaQt
26th April 2019, 11:06
First thank for your reply and just only today i restart to work on my project.
I load the file in format .zip about what i have done, by following your suggestion (it is write in right english? i write from Italy). I have to test it.
1)It is right to call the procedure udpSocket1->close(); before open a new bind? and it is all that i have to do to close it?
2)I find this procedure to get IP+SubnetMask+MAC of the current machine on an other post; why the printed information of MAC is empty, can you explain me the possible cause/guilty of this mistake?
Now the code:
-------------------------------------------------------------------------------------------------------------------------
QString localhostname = QHostInfo::localHostName();
QString localhostIP;
QList<QHostAddress> hostList = QHostInfo::fromName(localhostname).addresses();
foreach (const QHostAddress& address, hostList) {
if (address.protocol() == QAbstractSocket::IPv4Protocol && address.isLoopback() == false) {
localhostIP = address.toString();
}
}
QString localMacAddress;
QString localNetmask;
foreach (const QNetworkInterface& networkInterface, QNetworkInterface::allInterfaces()) {
foreach (const QNetworkAddressEntry& entry, networkInterface.addressEntries()) {
if (entry.ip().toString() == localhostIP) {
localMacAddress = networkInterface.hardwareAddress();
localNetmask = entry.netmask().toString();
break;
}
}
}
qDebug() << "Localhost name: " << localhostname;
qDebug() << "IP = " << localhostIP;
qDebug() << "MAC = " << localMacAddress;
qDebug() << "Netmask = " << localNetmask;
-------------------------------------------------------------------------------------------------------------------------
Thank you.

Added after 37 minutes:

now i want to find even the number of ports is it in use, i'm gonig to try it, so if you can help me?
if i find a solution i post it.
Thank you.