kma005
8th March 2018, 04:11
Hello,
I am unable to emit() a signal from the MainWindow object to a worker thread that will send & receive UDP Data.
The goal is to learn how to communicate from the GUI thread to the UDP thread.
***I do not understand why the SLOT is not working. I used the Mandlebrot example but in reverse, by communicating from GUI to thread. I tried QT4 & QT5 connect(signal, slot) functions without success. I get zero errors/warnings @ compile time***
Mandlebrot example:
connect(&thread, SIGNAL(renderedImage(QImage,double)), this, SLOT(updatePixmap(QImage,double)));
Mine in mainwindow.cpp:
connect( this, SIGNAL(&MainWindow::runInitializeInthreadUDP), threadObj, SLOT(&MyUDP::Initialize), Qt::QueuedConnection);
They only message I get from the "Application Output" is:
QObject::connect: Parentheses expected, signal MainWindow::&MainWindow::runInitializeInthreadUDP in mainwindow.cpp:36
Please see the attached code and if anyone is able to help, that would be very much appreciated.
If more info is needed, please ask.
//main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
qDebug()<<"From main GUI thread: "<<QThread::currentThreadId();
//Create GUI, but it is not shown until GUI.show is called
MainWindow GUI;
//generate GUI screen when this main function is finished
GUI.show();
return a.exec();
}
//mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QtCore>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0); //Class constructor
private:
Ui::MainWindow *ui;
signals:
void runInitializeInthreadUDP();
private slots:
void on_pushButton_clicked();
};
#endif // MAINWINDOW_H
//mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtCore>
#include "myudp.h"
#include "myThread.h"
myThread* threadObj = new myThread();
Worker* worker = new Worker();
//MainWindow Class Constructor
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//Create UDP object and startup worker thread
//https://wiki.qt.io/QThreads_general_usage
MyUDP udpObj;
udpObj.moveToThread(threadObj);
connect(worker, SIGNAL (&Worker::threadFinishedSignal), threadObj, SLOT (quit()));
connect(worker, SIGNAL (&Worker::threadFinishedSignal), worker, SLOT (deleteLater()));
connect(threadObj, SIGNAL (&Worker::threadFinishedSignal), threadObj, SLOT (deleteLater()));
threadObj->start();
//
//
//THIS NEXT PART DOES NOT WORK(Initialize() SLOT() function is never called)!!!!
//
//
//initialize UDP ports
//QT5 VERSION:
connect( this, SIGNAL(&MainWindow::runInitializeInthreadUDP), threadObj, SLOT(&MyUDP::Initialize), Qt::QueuedConnection);
//QT4 VERSION:
// connect( this, SIGNAL(runInitializeInthreadUDP()), threadObj, SLOT(Initialize()), Qt::QueuedConnection);
emit runInitializeInthreadUDP();
}
//also does not work when pressing button on GUI (this _clicked function runs, but does not call SLOT &MyUDP::Initialize)
void MainWindow::on_pushButton_clicked()
{
emit runInitializeInthreadUDP();
}
//mythread.h
//#ifndef WORKERTHREAD_H
//#define WORKERTHREAD_H
#include <QtCore>
//http://blog.debao.me/2013/08/how-to-use-qthread-in-the-right-way-part-1/
class myThread : public QThread
{
Q_OBJECT
private:
void run()
{
qDebug()<<"From worker thread: "<<currentThreadId();
connect(this, &QThread::finished, this, &QObject::deleteLater);
exec();
}
};
//https://wiki.qt.io/QThreads_general_usage
class Worker : public QObject {
Q_OBJECT
signals:
void threadFinishedSignal();
};
//#endif // WORKERTHREAD_H
//myudp.h
#ifndef UDP_H
#define UDP_H
//Base class QObject
#include <QUdpSocket>
#include <QtCore>
class MyUDP : public QObject
{
Q_OBJECT
public:
MyUDP(); //Constructor for UDP Class Object
~MyUDP(); //Destructor for UDP Class Object
private:
QUdpSocket *socket;
public slots:
void UDPreadInputData();
//Setup UDP port and connect port to fire function each time a UDP packet is received
void Initialize();
};
#endif // UDP_H
//myudp.cpp
#include "myudp.h"
#include <QtCore>
//Settings for UDP addresses
QHostAddress remoteAddress = QHostAddress("192.168.1.1");
QHostAddress localAddress = QHostAddress("192.168.1.2");
quint16 sendPort = 1234;
quint16 receivePort = 5678;
//UDP buffer that will contain the data received from microcontroller
QByteArray Buffer;
MyUDP::MyUDP() //Constructor for UDP Class Object
{
}
MyUDP::~MyUDP() //Destructor for UDP Class Object
{
}
void MyUDP::Initialize()
{
socket = new QUdpSocket(this);
//We need to bind the UDP socket to an address and a port
// socket->bind(QHostAddress::LocalHost,receivePort);
socket->bind(localAddress,receivePort);
//Call the "UDPreadyRead" function each time the socket gets data on the defined UDP port
connect(socket,SIGNAL(readyRead()),this,SLOT(UDPre adInputData()));
qDebug()<<"UDP worker thread initialized";
}
//Read something
void MyUDP::UDPreadInputData()
{
Buffer.resize(socket->pendingDatagramSize());
int bufferSize = Buffer.size();
//read sing UDP packet from hardware ethernet tranceiver on computer
socket->readDatagram(Buffer.data(), bufferSize, &remoteAddress, &receivePort);
// http://lists.qt-project.org/pipermail/qt-interest-old/2009-June/008318.html
// Read float32 data types out with a QDataStream
QDataStream ds( Buffer.mid( 0, bufferSize ) );
//By default, a QDataStream is big endian and must be flipped depending on "processor architecture".
ds.setByteOrder(QDataStream::LittleEndian);
ds.setFloatingPointPrecision(QDataStream::SinglePr ecision);
//Throw out UDP Ethernet header and two bytes that are unused at beginning of packet (10 bytes)
for(int i; i<5; i++)
{
qint16 temp; //each int16 is 2 bytes
ds >> temp;
}
//Read the first two "start of sample bytes"
qint16 HeaderByte1;
ds >> HeaderByte1; //54321 start of sample int16
}
I am unable to emit() a signal from the MainWindow object to a worker thread that will send & receive UDP Data.
The goal is to learn how to communicate from the GUI thread to the UDP thread.
***I do not understand why the SLOT is not working. I used the Mandlebrot example but in reverse, by communicating from GUI to thread. I tried QT4 & QT5 connect(signal, slot) functions without success. I get zero errors/warnings @ compile time***
Mandlebrot example:
connect(&thread, SIGNAL(renderedImage(QImage,double)), this, SLOT(updatePixmap(QImage,double)));
Mine in mainwindow.cpp:
connect( this, SIGNAL(&MainWindow::runInitializeInthreadUDP), threadObj, SLOT(&MyUDP::Initialize), Qt::QueuedConnection);
They only message I get from the "Application Output" is:
QObject::connect: Parentheses expected, signal MainWindow::&MainWindow::runInitializeInthreadUDP in mainwindow.cpp:36
Please see the attached code and if anyone is able to help, that would be very much appreciated.
If more info is needed, please ask.
//main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
qDebug()<<"From main GUI thread: "<<QThread::currentThreadId();
//Create GUI, but it is not shown until GUI.show is called
MainWindow GUI;
//generate GUI screen when this main function is finished
GUI.show();
return a.exec();
}
//mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QtCore>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0); //Class constructor
private:
Ui::MainWindow *ui;
signals:
void runInitializeInthreadUDP();
private slots:
void on_pushButton_clicked();
};
#endif // MAINWINDOW_H
//mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QtCore>
#include "myudp.h"
#include "myThread.h"
myThread* threadObj = new myThread();
Worker* worker = new Worker();
//MainWindow Class Constructor
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
//Create UDP object and startup worker thread
//https://wiki.qt.io/QThreads_general_usage
MyUDP udpObj;
udpObj.moveToThread(threadObj);
connect(worker, SIGNAL (&Worker::threadFinishedSignal), threadObj, SLOT (quit()));
connect(worker, SIGNAL (&Worker::threadFinishedSignal), worker, SLOT (deleteLater()));
connect(threadObj, SIGNAL (&Worker::threadFinishedSignal), threadObj, SLOT (deleteLater()));
threadObj->start();
//
//
//THIS NEXT PART DOES NOT WORK(Initialize() SLOT() function is never called)!!!!
//
//
//initialize UDP ports
//QT5 VERSION:
connect( this, SIGNAL(&MainWindow::runInitializeInthreadUDP), threadObj, SLOT(&MyUDP::Initialize), Qt::QueuedConnection);
//QT4 VERSION:
// connect( this, SIGNAL(runInitializeInthreadUDP()), threadObj, SLOT(Initialize()), Qt::QueuedConnection);
emit runInitializeInthreadUDP();
}
//also does not work when pressing button on GUI (this _clicked function runs, but does not call SLOT &MyUDP::Initialize)
void MainWindow::on_pushButton_clicked()
{
emit runInitializeInthreadUDP();
}
//mythread.h
//#ifndef WORKERTHREAD_H
//#define WORKERTHREAD_H
#include <QtCore>
//http://blog.debao.me/2013/08/how-to-use-qthread-in-the-right-way-part-1/
class myThread : public QThread
{
Q_OBJECT
private:
void run()
{
qDebug()<<"From worker thread: "<<currentThreadId();
connect(this, &QThread::finished, this, &QObject::deleteLater);
exec();
}
};
//https://wiki.qt.io/QThreads_general_usage
class Worker : public QObject {
Q_OBJECT
signals:
void threadFinishedSignal();
};
//#endif // WORKERTHREAD_H
//myudp.h
#ifndef UDP_H
#define UDP_H
//Base class QObject
#include <QUdpSocket>
#include <QtCore>
class MyUDP : public QObject
{
Q_OBJECT
public:
MyUDP(); //Constructor for UDP Class Object
~MyUDP(); //Destructor for UDP Class Object
private:
QUdpSocket *socket;
public slots:
void UDPreadInputData();
//Setup UDP port and connect port to fire function each time a UDP packet is received
void Initialize();
};
#endif // UDP_H
//myudp.cpp
#include "myudp.h"
#include <QtCore>
//Settings for UDP addresses
QHostAddress remoteAddress = QHostAddress("192.168.1.1");
QHostAddress localAddress = QHostAddress("192.168.1.2");
quint16 sendPort = 1234;
quint16 receivePort = 5678;
//UDP buffer that will contain the data received from microcontroller
QByteArray Buffer;
MyUDP::MyUDP() //Constructor for UDP Class Object
{
}
MyUDP::~MyUDP() //Destructor for UDP Class Object
{
}
void MyUDP::Initialize()
{
socket = new QUdpSocket(this);
//We need to bind the UDP socket to an address and a port
// socket->bind(QHostAddress::LocalHost,receivePort);
socket->bind(localAddress,receivePort);
//Call the "UDPreadyRead" function each time the socket gets data on the defined UDP port
connect(socket,SIGNAL(readyRead()),this,SLOT(UDPre adInputData()));
qDebug()<<"UDP worker thread initialized";
}
//Read something
void MyUDP::UDPreadInputData()
{
Buffer.resize(socket->pendingDatagramSize());
int bufferSize = Buffer.size();
//read sing UDP packet from hardware ethernet tranceiver on computer
socket->readDatagram(Buffer.data(), bufferSize, &remoteAddress, &receivePort);
// http://lists.qt-project.org/pipermail/qt-interest-old/2009-June/008318.html
// Read float32 data types out with a QDataStream
QDataStream ds( Buffer.mid( 0, bufferSize ) );
//By default, a QDataStream is big endian and must be flipped depending on "processor architecture".
ds.setByteOrder(QDataStream::LittleEndian);
ds.setFloatingPointPrecision(QDataStream::SinglePr ecision);
//Throw out UDP Ethernet header and two bytes that are unused at beginning of packet (10 bytes)
for(int i; i<5; i++)
{
qint16 temp; //each int16 is 2 bytes
ds >> temp;
}
//Read the first two "start of sample bytes"
qint16 HeaderByte1;
ds >> HeaderByte1; //54321 start of sample int16
}