Re[6]: Помогите с вопросом
От: milkpot Россия  
Дата: 18.04.24 16:45
Оценка:
Здравствуйте, 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);
    }
};
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.