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)));
connect(&thread, SIGNAL(renderedImage(QImage,double)), this, SLOT(updatePixmap(QImage,double)));
To copy to clipboard, switch view to plain text mode
Mine in mainwindow.cpp:
connect( this, SIGNAL(&MainWindow::runInitializeInthreadUDP), threadObj, SLOT(&MyUDP::Initialize), Qt::QueuedConnection);
connect( this, SIGNAL(&MainWindow::runInitializeInthreadUDP), threadObj, SLOT(&MyUDP::Initialize), Qt::QueuedConnection);
To copy to clipboard, switch view to plain text mode
They only message I get from the "Application Output" is:
QObject::connect: Parentheses expected,
signal MainWindow
::&MainWindow
::runInitializeInthreadUDP in mainwindow.
cpp:36
QObject::connect: Parentheses expected, signal MainWindow::&MainWindow::runInitializeInthreadUDP in mainwindow.cpp:36
To copy to clipboard, switch view to plain text mode
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[])
{
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();
}
#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();
}
To copy to clipboard, switch view to plain text mode
//mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QtCore>
namespace Ui {
class MainWindow;
}
{
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
#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
To copy to clipboard, switch view to plain text mode
//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
) : 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();
}
#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();
}
To copy to clipboard, switch view to plain text mode
//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/
{
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
Q_OBJECT
signals:
void threadFinishedSignal();
};
//#endif // WORKERTHREAD_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
To copy to clipboard, switch view to plain text mode
//myudp.h
#ifndef UDP_H
#define UDP_H
//Base class QObject
#include <QUdpSocket>
#include <QtCore>
{
Q_OBJECT
public:
MyUDP(); //Constructor for UDP Class Object
~MyUDP(); //Destructor for UDP Class Object
private:
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
#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
To copy to clipboard, switch view to plain text mode
//myudp.cpp
#include "myudp.h"
#include <QtCore>
//Settings for UDP addresses
quint16 sendPort = 1234;
quint16 receivePort = 5678;
//UDP buffer that will contain the data received from microcontroller
MyUDP::MyUDP() //Constructor for UDP Class Object
{
}
MyUDP::~MyUDP() //Destructor for UDP Class Object
{
}
void MyUDP::Initialize()
{
//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(UDPreadInputData()));
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
//By default, a QDataStream is big endian and must be flipped depending on "processor architecture".
ds.
setFloatingPointPrecision(QDataStream::SinglePrecision);
//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
}
#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(UDPreadInputData()));
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::SinglePrecision);
//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
}
To copy to clipboard, switch view to plain text mode
Bookmarks