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. unsync function , QSocketNotifier & Cannot move to target thread
Forum Updated to NodeBB v4.3 + New Features

unsync function , QSocketNotifier & Cannot move to target thread

Scheduled Pinned Locked Moved Solved General and Desktop
13 Posts 3 Posters 637 Views 1 Watching
  • 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.
  • _ Offline
    _ Offline
    __d4ve__
    wrote on last edited by
    #1

    Hi ,

    Here is the flow of tray Icon app syncing with server and the problem.

    Client* client = Client::instance();  // Singleton instance of Client
    
    • Client instance created on main()
    QAction::connect(actionSync, &QAction::triggered, clickHandler, &MenuClickHandler::syncApplication);
    
    • actionSync triggers MenuClickHandler::syncApplication

    • syncApplication()

    • initSync() runs and connects to the server

    The notification i get is :

    QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread
    
    void MenuClickHandler::syncApplication()
    {
    
        QThread* thread  = new QThread(this);
        Client::instance()->moveToThread(thread);
    
        if(Client::instance()->sync)
        {
            thread->quit();
            Client::instance()->disconnectSync();
            return;
        }
    
        connect(thread, &QThread::started, [=](){
            qDebug() << "Thread started - syncApplication";
            //Client client;
            Client::instance()->initSync();
    
            while (Client::instance()->sync == true) {
                qDebug() << "Data Receiving loop.";
                qDebug() << "Client->sync = " << Client::instance()->sync;
                Client::instance()->DataReceived();
            }
    
            // Emit a finished signal to allow thread cleanup
            thread->quit();
        });
    
        connect(thread, &QThread::finished, thread, &QThread::deleteLater);
    
        thread->start();
    }
    

    Here is some output :

    From main()

    Client thread: QThread(0x19f82244350)
    Current thread: QThread(0x19f82244350)
    

    From syncAppliaction()

    Thread started - syncApplication
    

    From initSync()

    sync request sent.
    QObject: Cannot create children for a parent that is in a different thread.
    (Parent is QTcpSocket(0x19f82251780), parent's thread is QThread(0x19f82244350), current thread is QThread(0x19f822c4660)
    

    everything works but with this notifications/errors

    I can't figure out how I should troubleshot that ?

    Christian EhrlicherC 1 Reply Last reply
    0
    • _ __d4ve__

      I use socket->waitForReadyRead(1000); instead readyRead() and yes connection_loop() does keep-alive every n seconds but I look for something more responsive

      Christian EhrlicherC Offline
      Christian EhrlicherC Offline
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #13

      @__d4ve__ said in unsync function , QSocketNotifier & Cannot move to target thread:

      I use socket->waitForReadyRead(1000);

      Again: do not block the event loop, use signals and slots.

      Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
      Visit the Qt Academy at https://academy.qt.io/catalog

      1 Reply Last reply
      1
      • _ __d4ve__

        Hi ,

        Here is the flow of tray Icon app syncing with server and the problem.

        Client* client = Client::instance();  // Singleton instance of Client
        
        • Client instance created on main()
        QAction::connect(actionSync, &QAction::triggered, clickHandler, &MenuClickHandler::syncApplication);
        
        • actionSync triggers MenuClickHandler::syncApplication

        • syncApplication()

        • initSync() runs and connects to the server

        The notification i get is :

        QSocketNotifier: Socket notifiers cannot be enabled or disabled from another thread
        
        void MenuClickHandler::syncApplication()
        {
        
            QThread* thread  = new QThread(this);
            Client::instance()->moveToThread(thread);
        
            if(Client::instance()->sync)
            {
                thread->quit();
                Client::instance()->disconnectSync();
                return;
            }
        
            connect(thread, &QThread::started, [=](){
                qDebug() << "Thread started - syncApplication";
                //Client client;
                Client::instance()->initSync();
        
                while (Client::instance()->sync == true) {
                    qDebug() << "Data Receiving loop.";
                    qDebug() << "Client->sync = " << Client::instance()->sync;
                    Client::instance()->DataReceived();
                }
        
                // Emit a finished signal to allow thread cleanup
                thread->quit();
            });
        
            connect(thread, &QThread::finished, thread, &QThread::deleteLater);
        
            thread->start();
        }
        

        Here is some output :

        From main()

        Client thread: QThread(0x19f82244350)
        Current thread: QThread(0x19f82244350)
        

        From syncAppliaction()

        Thread started - syncApplication
        

        From initSync()

        sync request sent.
        QObject: Cannot create children for a parent that is in a different thread.
        (Parent is QTcpSocket(0x19f82251780), parent's thread is QThread(0x19f82244350), current thread is QThread(0x19f822c4660)
        

        everything works but with this notifications/errors

        I can't figure out how I should troubleshot that ?

        Christian EhrlicherC Offline
        Christian EhrlicherC Offline
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on last edited by
        #2

        @__d4ve__ said in unsync function , QSocketNotifier & Cannot move to target thread:

        can't figure out how I should troubleshot that ?

        Don't use a global static, don't use threads at all because they are not needed here.

        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
        Visit the Qt Academy at https://academy.qt.io/catalog

        1 Reply Last reply
        1
        • _ Offline
          _ Offline
          __d4ve__
          wrote on last edited by
          #3

          GUI will be unresponsive other wise , why not using global static ?

          Christian EhrlicherC 1 Reply Last reply
          0
          • _ __d4ve__

            GUI will be unresponsive other wise , why not using global static ?

            Christian EhrlicherC Offline
            Christian EhrlicherC Offline
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote on last edited by
            #4

            @__d4ve__ said in unsync function , QSocketNotifier & Cannot move to target thread:

            GUI will be unresponsive other wise

            Use signals and slots and a/or a QTimer. No need to block anything.
            Globlals, especially QObject one are bad design.

            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
            Visit the Qt Academy at https://academy.qt.io/catalog

            1 Reply Last reply
            1
            • _ Offline
              _ Offline
              __d4ve__
              wrote on last edited by
              #5

              Ok ,
              signals and slots ,
              I have Client variable that supposed to be global variable and used in another classes

              1 Reply Last reply
              0
              • _ Offline
                _ Offline
                __d4ve__
                wrote on last edited by
                #6

                Used QTimer , makes GUI freeze :

                void MenuClickHandler::syncApplication()
                {
                    if(Client::instance()->sync)
                    {
                        Client::instance()->disconnectSync();
                        return;
                    }
                
                    QTimer* timer = new QTimer(this);  // Use a timer instead of a new thread
                
                    connect(timer, &QTimer::timeout, [=](){
                
                        Client::instance()->initSync();
                
                        while (Client::instance()->sync == true) {
                            qDebug() << "Data Receiving loop.";
                            qDebug() << "Client->sync = " << Client::instance()->sync;
                            Client::instance()->DataReceived();
                        }
                
                        });
                        timer->start(1000);
                }
                

                I can see that something wrong with the design but as far as i know Qt usage , Qthreads or instance() I would like to hear what other options there , if i Initiate object on main() , what's the right way to connect it ?

                I have QAction on main()

                QAction::connect(actionSync, &QAction::triggered, clickHandler, &MenuClickHandler::syncApplication);
                

                that changes it label to 'unsync' after successful syncing another click should unsync it .
                this scenario may confuse so what should be done with signal slot ?

                first click syncs
                the second unsyncs ( on successful synced client only )
                recommended not using Qthreads , Client instance()

                Christian EhrlicherC 1 Reply Last reply
                0
                • _ __d4ve__

                  Used QTimer , makes GUI freeze :

                  void MenuClickHandler::syncApplication()
                  {
                      if(Client::instance()->sync)
                      {
                          Client::instance()->disconnectSync();
                          return;
                      }
                  
                      QTimer* timer = new QTimer(this);  // Use a timer instead of a new thread
                  
                      connect(timer, &QTimer::timeout, [=](){
                  
                          Client::instance()->initSync();
                  
                          while (Client::instance()->sync == true) {
                              qDebug() << "Data Receiving loop.";
                              qDebug() << "Client->sync = " << Client::instance()->sync;
                              Client::instance()->DataReceived();
                          }
                  
                          });
                          timer->start(1000);
                  }
                  

                  I can see that something wrong with the design but as far as i know Qt usage , Qthreads or instance() I would like to hear what other options there , if i Initiate object on main() , what's the right way to connect it ?

                  I have QAction on main()

                  QAction::connect(actionSync, &QAction::triggered, clickHandler, &MenuClickHandler::syncApplication);
                  

                  that changes it label to 'unsync' after successful syncing another click should unsync it .
                  this scenario may confuse so what should be done with signal slot ?

                  first click syncs
                  the second unsyncs ( on successful synced client only )
                  recommended not using Qthreads , Client instance()

                  Christian EhrlicherC Offline
                  Christian EhrlicherC Offline
                  Christian Ehrlicher
                  Lifetime Qt Champion
                  wrote on last edited by
                  #7

                  @__d4ve__ said in unsync function , QSocketNotifier & Cannot move to target thread:

                  while (Client::instance()->sync == true) {

                  I mean -what do you expect when you block the event loop... let Client emit a signal when the data was received.

                  Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                  Visit the Qt Academy at https://academy.qt.io/catalog

                  1 Reply Last reply
                  1
                  • _ Offline
                    _ Offline
                    __d4ve__
                    wrote on last edited by
                    #8

                    Changed the code but the GUI still not responsive :

                    void MenuClickHandler::syncApplication()
                    {
                        qDebug() << Client::instance()->socket->isOpen() ;
                        if(Client::instance()->sync && Client::instance()->socket->isOpen() )
                        {
                            Client::instance()->disconnectSync();
                            return;
                        }
                    
                        QTimer* timer = new QTimer(this);  // Use a timer instead of a new thread
                    
                        connect(timer, &QTimer::timeout, [=](){
                    
                            Client::instance()->initSync();
                    
                            while (Client::instance()->sync == true) {
                                qDebug() << "Data Receiving loop.";
                                qDebug() << "Client->sync = " << Client::instance()->sync;
                                Client::instance()->DataReceived();
                            }
                    
                            });
                            timer->start(1000);
                    }
                    

                    Syncs successfully but not responsive afterwards

                    Pl45m4P 1 Reply Last reply
                    0
                    • _ __d4ve__

                      Changed the code but the GUI still not responsive :

                      void MenuClickHandler::syncApplication()
                      {
                          qDebug() << Client::instance()->socket->isOpen() ;
                          if(Client::instance()->sync && Client::instance()->socket->isOpen() )
                          {
                              Client::instance()->disconnectSync();
                              return;
                          }
                      
                          QTimer* timer = new QTimer(this);  // Use a timer instead of a new thread
                      
                          connect(timer, &QTimer::timeout, [=](){
                      
                              Client::instance()->initSync();
                      
                              while (Client::instance()->sync == true) {
                                  qDebug() << "Data Receiving loop.";
                                  qDebug() << "Client->sync = " << Client::instance()->sync;
                                  Client::instance()->DataReceived();
                              }
                      
                              });
                              timer->start(1000);
                      }
                      

                      Syncs successfully but not responsive afterwards

                      Pl45m4P Offline
                      Pl45m4P Offline
                      Pl45m4
                      wrote on last edited by
                      #9

                      @__d4ve__ said in unsync function , QSocketNotifier & Cannot move to target thread:

                      connect(timer, &QTimer::timeout, ={

                          Client::instance()->initSync();
                      
                          while (Client::instance()->sync == true) {
                              qDebug() << "Data Receiving loop.";
                              qDebug() << "Client->sync = " << Client::instance()->sync;
                              Client::instance()->DataReceived();
                          }
                      
                          });
                          timer->start(1000);
                      

                      I think the while loop is still blocking.

                      So better something like

                      QTimer::singleShot(0, this, ()[=]{
                      
                      // sync here
                      
                      });
                      

                      If debugging is the process of removing software bugs, then programming must be the process of putting them in.

                      ~E. W. Dijkstra

                      1 Reply Last reply
                      0
                      • _ Offline
                        _ Offline
                        __d4ve__
                        wrote on last edited by
                        #10

                        The problem with SingleShot function is that its good as written for 'single shot' what makes the app not responsive as desired in period of times.

                        I changed program design and currently sync loop runs on SingleShot but I need alternative
                        not using QThreads and while loop leaves me with maybe connect on some terms

                        I have :

                        sync(): init connection

                        connection_loop() : maintains connection

                        receiveData() : receives data from server

                        Christian EhrlicherC 1 Reply Last reply
                        0
                        • _ __d4ve__

                          The problem with SingleShot function is that its good as written for 'single shot' what makes the app not responsive as desired in period of times.

                          I changed program design and currently sync loop runs on SingleShot but I need alternative
                          not using QThreads and while loop leaves me with maybe connect on some terms

                          I have :

                          sync(): init connection

                          connection_loop() : maintains connection

                          receiveData() : receives data from server

                          Christian EhrlicherC Offline
                          Christian EhrlicherC Offline
                          Christian Ehrlicher
                          Lifetime Qt Champion
                          wrote on last edited by
                          #11

                          @__d4ve__ said in unsync function , QSocketNotifier & Cannot move to target thread:

                          connection_loop() : maintains connection

                          What does this mean? What has to be done in there? A keep-alive every n seconds? Use a QTimer.

                          receiveData() : receives data from server

                          Use the readyRead() signal and process your data.

                          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                          Visit the Qt Academy at https://academy.qt.io/catalog

                          1 Reply Last reply
                          1
                          • _ Offline
                            _ Offline
                            __d4ve__
                            wrote on last edited by __d4ve__
                            #12

                            I use socket->waitForReadyRead(1000); instead readyRead() and yes connection_loop() does keep-alive every n seconds but I look for something more responsive

                            Christian EhrlicherC 1 Reply Last reply
                            0
                            • _ __d4ve__

                              I use socket->waitForReadyRead(1000); instead readyRead() and yes connection_loop() does keep-alive every n seconds but I look for something more responsive

                              Christian EhrlicherC Offline
                              Christian EhrlicherC Offline
                              Christian Ehrlicher
                              Lifetime Qt Champion
                              wrote on last edited by
                              #13

                              @__d4ve__ said in unsync function , QSocketNotifier & Cannot move to target thread:

                              I use socket->waitForReadyRead(1000);

                              Again: do not block the event loop, use signals and slots.

                              Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                              Visit the Qt Academy at https://academy.qt.io/catalog

                              1 Reply Last reply
                              1
                              • _ __d4ve__ has marked this topic as solved on

                              • Login

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