Здравствуйте, Igore, Вы писали:
M>>В выводе приложения QtCreator'а после закрытия приложения появляются записи:
M>>QThread: Destroyed while thread is still running
I>вызван m_Thread.quit();, но нет ожидания его завершения(waitForFinished), потом начинает работать ~Window и m_Thread просто уничтожается во время работы
M>>QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread
I>когда происходит m_Thread.quit(); начинается завершение потока, finished это уже потока нет, а в нем создан socket, который нужно удалить в том же потоке где он был создан
I>Ну в примере же по другому
I>I>m_Receiver.stop(); // Ставим в очередь потока вызов doStop
I>m_Thread.quit(); // Завершаем поток
I>m_Thread.waitForFinished(); // Ждем когда отработает из очереди doStop и нормально завершим внутреннее состояние
I>
//----
class Window : public QWidget
{
Q_OBJECT
private:
Worker2 worker;
QThread m_Thread;
Worker3 worker3;
QThread m_Thread3;
};
Window::Window()
{
//---+
worker.moveToThread( &m_Thread );
connect(&m_Thread, &QThread::finished, &worker, &QObject::deleteLater);
connect(&worker, &Worker2::resultReady, this, &Window::appendtoLogListBox);
connect(&worker, &Worker2::sendData, this, &Window::displayImage);
worker.startStrm();
m_Thread.start(QThread::TimeCriticalPriority);
//----
//---+
worker3.moveToThread( &m_Thread3 );
connect(&m_Thread3, &QThread::finished, &worker3, &QObject::deleteLater);
//connect(&worker3, &Worker3::resultReady, this, &Window::appendtoLogListBox);
worker3.startStrm3();
m_Thread3.start(QThread::HighPriority);
//----
}
Window::~Window()
{
worker.stopStrm();
m_Thread.quit();
b_result=m_Thread.wait(200);
qDebug() << "m_Thread.wait(200) = " << b_result;// Не печатается
//--- Если Worker3 нет, то печатается
worker3.stopStrm3();
m_Thread3.quit();
b_result=m_Thread3.wait(200);
qDebug() << "m_Thread3.wait(200) = " << b_result;// Не печатается
}
void Window::displayImage(const QImage& img)
{
img1=img;
helper.img2=img1;
update();
return;
}
void Window::launchWrite()
{
QByteArray byte_array;
byte_array.resize(648);
for(int j=0;j<480;j++)
{
for(int i=0;i<648;i++)
{
byte_array[i]=i;
}
// worker.writeToUdp(byte_array);
worker3.writeToUdp3(byte_array);// Выводится сообщение в консоль QtCreator:
//QObject: Cannot create children for a parent that is in a different thread.
//(Parent is QUdpSocket(0x1e03938), parent's thread is QThread(0x61fdc4), current thread is QThread(0x1692d80)
//Или надо делать вызов через signal-slot?
//Если убрать Worker3 и реализовать через Worker2, то сообщение не появляется
//----
}
return;
}
//-------------------------------------
class Worker2 : public QObject
{
Q_OBJECT
private:
QScopedPointer<QUdpSocket> m_pSocket;
public:
void startStrm()
{
QMetaObject::invokeMethod(this, "doStart", Qt::QueuedConnection);
}
void stopStrm()
{
QMetaObject::invokeMethod(this, "doStop", Qt::QueuedConnection);
}
public slots:
void doStart()
{
m_pSocket.reset( new QUdpSocket(this) );
result=m_pSocket->bind( QHostAddress::AnyIPv4 , 50012);
connect(m_pSocket.data()/*socket*/, &QUdpSocket::readyRead,this,&Worker2::readPendingDatagrams);
}
void doStop()
{
disconnect(m_pSocket.data()/*socket*/, &QUdpSocket::readyRead,this,&Worker2::readPendingDatagrams);
m_pSocket.reset();
}
public:
void writeToUdp(const QByteArray& qBinArray)
{
port_large=50012;
retData=m_pSocket->writeDatagram(qBinArray,QHostAddress::LocalHost, port_large);
}
void readPendingDatagrams()
{
QByteArray buffer;
while(m_pSocket->hasPendingDatagrams())
{
size_of_data=m_pSocket->pendingDatagramSize();
if(-1==size_of_data) continue;
buffer.resize(m_pSocket->pendingDatagramSize());
ret_value=m_pSocket->readDatagram(buffer.data(),buffer.size(),&sender,&senderPort);
writeData(buffer);
setUdpData(buffer);
}
}
signals:
void resultReady(const QString &result);
void sendData(const QImage &image);
void writeUdpData(const QByteArray & );
};
//--- Вводим класс Worker3, чтобы производить запись датаграмм в сокет
class Worker3 : public QObject
{
Q_OBJECT
private:
QScopedPointer<QUdpSocket> m_pSocket3;
public:
void startStrm3()
{
QMetaObject::invokeMethod(this, "doStart3", Qt::QueuedConnection);
}
void stopStrm3()
{
QMetaObject::invokeMethod(this, "doStop3", Qt::QueuedConnection);
}
public slots:
void doStart3()
{
m_pSocket3.reset( new QUdpSocket(this) );
}
void doStop3()
{
m_pSocket3.reset();
}
public:
void writeToUdp3(const QByteArray& qBinArray)
{
port_large= 50012;
retData=/*socket*/m_pSocket3->writeDatagram(qBinArray,QHostAddress::LocalHost, port_large);
}
};