I'm trying to receive some packets using a udpReceiver
class that I have written using qUdpSocket
in a separate QThread
:
class udpThread : public QThread
{
private:
QObject * parent;
public:
udpThread(QObject * parent = 0)
{
this->parent = parent;
}
void run()
{
UdpReceiver * test = new UdpReceiver(parent);
}
};
class UdpReceiver : public QObject
{
Q_OBJECT
private:
QUdpSocket * S;
int port;
public:
UdpReceiver(QObject* parent = 0) : QObject(parent)
{
port = 9003;
initialize();
}
UdpReceiver(int p,QObject* parent = 0) : QObject(parent)
{
port = p;
initialize();
}
void initialize()
{
S = new QUdpSocket();
S->bind(port);
S->connect(S,SIGNAL(readyRead()),this,SLOT(readPendingDiagrams()));
qDebug() << "Waiting for UDP data from port " << port << " ... \n";
}
public slots:
void readPendingDiagrams()
{
while(S->waitForReadyRead())
{
QByteArray datagram;
datagram.resize(S->pendingDatagramSize());
QHostAddress sender;
quint16 senderPort;
S->readDatagram(datagram.data(), datagram.size(),&sender, &senderPort);
qDebug() << datagram.size() << " bytes received .... \n";
qDebug() << " bytes received .... \n";
}
}
};
And here is the main()
method :
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
// UdpReceiver * net = new UdpReceiver();
MainWindow w;
udpThread * ut = new udpThread();
ut->start();
w.show();
return a.exec();
}
Now when I use the udpReceiver
class to get the packets without the QThread
it works just fine, but when I use the udpThread
class it doesn't get the packets or at least the raedyread()
signal does not activate some how.
When I try to get the packets without the QThread
my GUI crashes somehow and the whole program hangs, that's why I want to use QThread
.
I appreciate if you could help me solve this :)
Regards,
You've fallen into the same trap as many do when working with threads in Qt: http://blog.qt.io/blog/2010/06/17/youre-doing-it-wrong/.
It is almost always a bad idea to subclass QThread (see http://woboq.com/blog/qthread-you-were-not-doing-so-wrong.html for counterexamples).
Change your code as follows to do it the "intended" way (create a new QThread
and call moveToThread
on your QObject
to move it to the new thread). You'll see from the output that the thread the UdpReceiver
is created on is not the same as the one it receives data on, which is what you want:
#include <QApplication>
#include <QDebug>
#include <QThread>
#include <QUdpSocket>
class UdpReceiver : public QObject
{
Q_OBJECT
private:
QUdpSocket * S;
int port;
public:
UdpReceiver(QObject* parent = 0) : QObject(parent)
{
qDebug() << "Construction thread:" << QThread::currentThreadId();
port = 9003;
initialize();
}
UdpReceiver(int p,QObject* parent = 0) : QObject(parent)
{
port = p;
initialize();
}
void initialize()
{
S = new QUdpSocket();
S->bind(port);
S->connect(S,SIGNAL(readyRead()),this,SLOT(readPendingDiagrams()));
qDebug() << "Waiting for UDP data from port " << port << " ... \n";
}
public slots:
void readPendingDiagrams()
{
qDebug() << "Reading thread:" << QThread::currentThreadId();
while(S->waitForReadyRead())
{
QByteArray datagram;
datagram.resize(S->pendingDatagramSize());
QHostAddress sender;
quint16 senderPort;
S->readDatagram(datagram.data(), datagram.size(),&sender, &senderPort);
qDebug() << datagram.size() << " bytes received .... \n";
qDebug() << " bytes received .... \n";
}
}
};
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QThread *t = new QThread();
t->start();
UdpReceiver * net = new UdpReceiver();
net->moveToThread(t);
return a.exec();
}
#include "main.moc"
I don't have your UI
code, so I don't know about any issues there. Feel free to post another question if you get stuck there and mention it in a comment and I'll try to help.