Есть гуи приложение, из которого создается класс Sock, который в свою очередь наследует QThread. Соответственно, класс Sock имеет виртуальный метод run, в котором создается экземпляр QTcpSocket и соединяются сигналы данного экземпляра со слотами класса Sock (connected, disconnected, readyRead) и потом происходит запрос соединения(connectToHost). Затем должен начаться циклический опрос данных с удаленного устройства. Но есть проблема: если зацыклить здесь опрос, но не запускается метод exec(), указаный в конце тела run(). Ну и понятно, что без exec() не работает event loop и не работает не одно событие... даже как таковая отправка данных по QTcpSocket->write(). Но если дать запуститься методу exec(), то я не понимаю где тогда запускать циклический опрос данных. Пробовал запускать циклический опрос из слота connected(), предполагая, что через этот слот опрос будет выполняться "параллельно" методу exec(), но в этом случает "виснет" главное окно, как будто опрос происходит в основном потоке (хотя по соединению сигнал-слот должен вызываться из потока). Метод moveToThread никакого эффекта не дает. В общем, прощу помощи найти рабочее решение для организации циклического опроса в потоке. Перечитал много веток на этом форуме и на других, но не смог найти в них что то полезное, к тому же большинство топиков посвящено созданию сервера в потоке. Для тестирования создал небольшой проект, его здесь и приведу:
MainWindow.cppMainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
sock = new Sock(this);
connect(sock, SIGNAL(getData(QByteArray)), this, SLOT(onGetData(QByteArray)));
sock->start(QThread::NormalPriority);
}
void MainWindow::onGetData(QByteArray data)
{
ui->lineEdit->setText(data.toHex());
}
sock.h#include <QThread>
#include <QTcpSocket>
class Sock : public QThread
{
Q_OBJECT
public:
explicit Sock(QObject *parent = 0);
void run();
signals:
void getData(QByteArray data);
public slots:
void onReadyRead();
void onConnect();
void onDisconnect();
private:
QTcpSocket *gsock;
void requestLoop();
};
sock.cpp#include "QtNetwork"
#include "sock.h"
Sock::Sock(QObject *parent) :
QThread(parent)
{
}
void Sock::onReadyRead()
{
qDebug("ready read");
qint64 bytes = gsock->bytesAvailable();
QByteArray data = gsock->read(bytes);
emit getData(data);
}
void Sock::onConnect()
{
qDebug("connect");
// requestLoop();
}
void Sock::onDisconnect()
{
qDebug("disconnect");
}
void Sock::run()
{
qDebug("run");
gsock = new QTcpSocket(0);
connect(gsock, SIGNAL(readyRead()), this, SLOT(onReadyRead()), Qt::QueuedConnection);
connect(gsock, SIGNAL(connected()), this, SLOT(onConnect()), Qt::QueuedConnection);
connect(gsock, SIGNAL(disconnected()), this, SLOT(onDisconnect()), Qt::QueuedConnection);
QHostAddress host;
host.setAddress("192.168.0.17");
gsock->connectToHost(host, 502);
if(!gsock->waitForConnected())
{
qDebug("connected faild");
return;
}
else
qDebug("connected success");
requestLoop();
qDebug("exec");
exec();
qDebug("stop exec");
}
void Sock::requestLoop()
{
QByteArray data;
data.append(QByteArray::fromHex("000100000006010350160002"));
while(1)
{
if (gsock->state() == QAbstractSocket::ConnectedState)
{
qDebug("write data");
gsock->write(data);
}
else
{
qDebug("no connected to write");
}
sleep(2);
}
}