Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QThread & Lost Queued-Signals

QThread & Lost Queued-Signals

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 2 Posters 1.9k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J.HilkJ Offline
    J.HilkJ Offline
    J.Hilk
    Moderators
    wrote on last edited by
    #1

    Hello everyone,

    I have the situation, that somehow signals from a different thread are lost, and I'm unsure why that is the case.

    The situation:
    I have a class SslSocket that is only depending on QObject

    class SslSocket : public QObject
    {
        Q_OBJECT
    
    public:
        SslSocket(QString host, int port, SmtpClient::ConnectionType connection);
        ~SslSocket();
    
        enum errorType{
            connectError,
            loginError,
            sendError
        };
        Q_ENUM(errorType)
    ...
    ...
    }
    

    In it, I'm using the asynchronus QSslSocket approch to communicate with a server. Even so I use readyRead and bytesWritten instead of the blocking functions I decided to wrap the class up in a seperated thread.

        SslSocket *smtp = new SslSocket("smtp.gmail.com",465,SmtpClient::SslConnection);
        QThread *t = new QThread();
        smtp->moveToThread(t);
    
        connect(t, &QThread::started,   smtp, &SslSocket::initSslSocket);
        connect(t, &QThread::finished,  smtp, &SslSocket::deleteLater);
        connect(t, &QThread::finished,  t,    &QThread::deleteLater);
    
        connect(this, &SmtpEmail::destroyed, t, &QThread::quit);
        connect(smtp, &SslSocket::errorMsg,         this, &SmtpEmail::errorManagement/*,Qt::DirectConnection*/); //<= Problem
    ...
    ...
    t->start();
    

    It is working as indetend, but while testing for potential Errors, I set the server to refuse the SSL-Handshake.
    Using qDebug I see that the SIGNAL errorMsg is emitted, but the SLOT errorManagement is not called, ever.

    But when I change the connection type from Qt::QueuedConnection to Qt::DirectConnection, the slot is called! The slot is also called, when I do not move smtp to the thread, but let it life in the main thread.

    Because the object lifes in a different thread I rather would not use DirectConnection if I can avoid it.

    So, anyone any idea what is going on ?

    Thanks


    Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


    Q: What's that?
    A: It's blue light.
    Q: What does it do?
    A: It turns blue.

    1 Reply Last reply
    0
    • J.HilkJ Offline
      J.HilkJ Offline
      J.Hilk
      Moderators
      wrote on last edited by
      #7

      I'm an Idiot.

      I overwrote QWidget::event to emit a signal in certain situations.

      bool SmtpEmail::event(QEvent *e)
      {
          if(e->type() == QEvent::MouseButtonPress ||
                  e->type() == QEvent::MouseButtonRelease ||
                  e->type() == QEvent::MouseMove ){
              QMouseEvent *ev =(QMouseEvent *)e;
              emit mouseEvent(ev->type(),mapToGlobal(ev->pos()));
          }
          return false;
      }
      

      what I should have written:

      bool SmtpEmail::event(QEvent *e)
      {
          if(e->type() == QEvent::MouseButtonPress ||
                  e->type() == QEvent::MouseButtonRelease ||
                  e->type() == QEvent::MouseMove ){
              QMouseEvent *ev =(QMouseEvent *)e;
              emit mouseEvent(ev->type(),mapToGlobal(ev->pos()));
          }
          return QFrame::event(e);
      }
      

      returning false als the default value aparently interrupt the QueuedConnection mechanic.


      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


      Q: What's that?
      A: It's blue light.
      Q: What does it do?
      A: It turns blue.

      1 Reply Last reply
      0
      • VRoninV Offline
        VRoninV Offline
        VRonin
        wrote on last edited by
        #2

        This looks like a typical case in which you don't have an event loop running or the event loop in the main thread is blocked (stuck in a while(true) or something similar)

        "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
        ~Napoleon Bonaparte

        On a crusade to banish setIndexWidget() from the holy land of Qt

        J.HilkJ 1 Reply Last reply
        1
        • VRoninV VRonin

          This looks like a typical case in which you don't have an event loop running or the event loop in the main thread is blocked (stuck in a while(true) or something similar)

          J.HilkJ Offline
          J.HilkJ Offline
          J.Hilk
          Moderators
          wrote on last edited by
          #3

          @VRonin hi,

          I'm quite sure that I'have a event loop and that it is running. I do call QThread::start() , queded-connections inside the threaded class are executed without problem as well. Also QThread::isrunning() returns true:

          I added the following to test:

          QTimer *timer = new QTimer();
              timer->setInterval(500);
              connect(timer, &QTimer::timeout, timer, [=]{
                  qDebug() << "Thread"<< QTime::currentTime().toString("ss.zzz"); 
                  emit errorMsg(QTime::currentTime().toString("ss.zzz"));
              });
              timer->start();
          
          connect(smtp, &SslSocket::errorMsg,         this, &SmtpEmail::errorManagement);
          connect(smtp, &SslSocket::errorMsg, smtp,[=](QString s){qDebug()<< "Queued:"<< s;},Qt::QueuedConnection );
              connect(smtp, &SslSocket::errorMsg, smtp,[=](QString s){qDebug()<< "Direct:"<< s;},Qt::DirectConnection );
          connect(smtp, &SslSocket::errorMsg, this, &SmtpEmail::msg, Qt::QueuedConnection);
              connect(smtp, &SslSocket::errorMsg, this, &SmtpEmail::msg, Qt::DirectConnection);
          
          void SmtpEmail::msg(QString s)
          {
              qDebug() << "Slot"<< s;
          }
          

          the result is:

          Thread "14.433"
          Direct: "14.433"
          Slot "14.433"
          Queued: "14.433"
          

          The queued connections, except the lambda one, are missing. And I'm not sure you can actually queue lambdas!?

          ...

          I don't think I blocked the main thread.

          • I don't use while loops in my main thread. Howerver there is one in the SslSocket class that I use to read the data, but it should not becalled before the readyread signal
          if(socket->canReadLine()){
                  while (socket->canReadLine())
                  ...
          }
          
          • I can resize the window without a problem
          • I do get information from my other worker thread, that is using a serialport

          Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


          Q: What's that?
          A: It's blue light.
          Q: What does it do?
          A: It turns blue.

          1 Reply Last reply
          0
          • J.HilkJ Offline
            J.HilkJ Offline
            J.Hilk
            Moderators
            wrote on last edited by
            #4

            OK, just made a clean project with this code:

                QTimer *timer = new QTimer();
                QThread *thread = new QThread();
                timer->moveToThread(thread);
                timer->setInterval(500);
                connect(timer, &QTimer::timeout, this, &MainWindow::mySlot);
                connect(thread, &QThread::started, timer, QOverload<>::of(&QTimer::start));
                thread->start();
            
            void MainWindow::mySlot()
            {
                qDebug() << "my Slot"<< QTime::currentTime().toString("mm.zzz");
            }
            

            It is calling the slot, like it should. If I copy and paste that one to my class where I have the problems, and adjust mySlot,

            the slot is not called....

            I'll have to look into it more. I defenitly messed up somewhere...


            Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


            Q: What's that?
            A: It's blue light.
            Q: What does it do?
            A: It turns blue.

            1 Reply Last reply
            1
            • VRoninV Offline
              VRoninV Offline
              VRonin
              wrote on last edited by
              #5

              could you post the code of SmtpEmail?

              "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
              ~Napoleon Bonaparte

              On a crusade to banish setIndexWidget() from the holy land of Qt

              J.HilkJ 1 Reply Last reply
              1
              • VRoninV VRonin

                could you post the code of SmtpEmail?

                J.HilkJ Offline
                J.HilkJ Offline
                J.Hilk
                Moderators
                wrote on last edited by
                #6

                @VRonin

                I have the code here, I took the liberty to obscure some strings and add sslsocket as well.


                Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                Q: What's that?
                A: It's blue light.
                Q: What does it do?
                A: It turns blue.

                1 Reply Last reply
                0
                • J.HilkJ Offline
                  J.HilkJ Offline
                  J.Hilk
                  Moderators
                  wrote on last edited by
                  #7

                  I'm an Idiot.

                  I overwrote QWidget::event to emit a signal in certain situations.

                  bool SmtpEmail::event(QEvent *e)
                  {
                      if(e->type() == QEvent::MouseButtonPress ||
                              e->type() == QEvent::MouseButtonRelease ||
                              e->type() == QEvent::MouseMove ){
                          QMouseEvent *ev =(QMouseEvent *)e;
                          emit mouseEvent(ev->type(),mapToGlobal(ev->pos()));
                      }
                      return false;
                  }
                  

                  what I should have written:

                  bool SmtpEmail::event(QEvent *e)
                  {
                      if(e->type() == QEvent::MouseButtonPress ||
                              e->type() == QEvent::MouseButtonRelease ||
                              e->type() == QEvent::MouseMove ){
                          QMouseEvent *ev =(QMouseEvent *)e;
                          emit mouseEvent(ev->type(),mapToGlobal(ev->pos()));
                      }
                      return QFrame::event(e);
                  }
                  

                  returning false als the default value aparently interrupt the QueuedConnection mechanic.


                  Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                  Q: What's that?
                  A: It's blue light.
                  Q: What does it do?
                  A: It turns blue.

                  1 Reply Last reply
                  0

                  • Login

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • Users
                  • Groups
                  • Search
                  • Get Qt Extensions
                  • Unsolved