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. Not getting past emit command.

Not getting past emit command.

Scheduled Pinned Locked Moved General and Desktop
12 Posts 2 Posters 3.0k 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.
  • A Offline
    A Offline
    andre
    wrote on last edited by
    #2

    You clearly have not done enough reading on the matter.

    In this scenario, you should not subclass QThread. Instead, use a worker object and move that to a thread managed by a (vanilla) QThread.

    The root of your problem is that you have created a slot on the manager of your thread (the QThread object), but that manager itself lives in the thread that created it in the first place.

    There is lots of information to be found on this issue, including in the QThread documentation itself.

    1 Reply Last reply
    0
    • A Offline
      A Offline
      achmed
      wrote on last edited by
      #3

      My Original approach was like you stated to move the worker object to a vanilla QThread. But then I ended up having other issues and compiling errors. People told me that the errors where caused because the object was not created in the 2nd thread where the worker object was moved to. I Will try it again and let you know what happens.

      1 Reply Last reply
      0
      • A Offline
        A Offline
        achmed
        wrote on last edited by
        #4

        Ok. The above code was just an example of the issue I was facing in another bigger program. I Rewrote the code back to the way It was, where I try moving the objects to a vanilla QThread. I Get the same two errors as before.

        On first run I usually get:

        @QObject: Cannot create children for a parent that is in a different thread.
        (Parent is QSerialPort(0xb1fc20), parent's thread is QThread(0x15819a70), current thread is QThread(0xb30d50)
        QObject: Cannot create children for a parent that is in a different thread.
        (Parent is QSerialPort(0xb1fc38), parent's thread is QThread(0x15819a70), current thread is QThread(0xb30d50)@

        on second run I sometimes get this error:
        @Invalid parameter passed to C runtime function.
        ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 16e80d50. Receiver 'MainWindowWindow' (of type 'QWidgetWindow') was created in thread 154b9a70", file kernel\qcoreapplication.cpp, line 521
        Invalid parameter passed to C runtime function.
        QObject::killTimers: timers cannot be stopped from another thread
        X:\MTEK\Programming\Contact Noise GUI\43\build-Contact_Noise-Desktop_Qt_5_3_MinGW_32bit-Debug\debug\Contact_Noise.exe exited with code 3@

        I Will post some of my code in the next couple of minutes.

        1 Reply Last reply
        0
        • A Offline
          A Offline
          achmed
          wrote on last edited by
          #5

          I have omitted code that I think might be unnecessary.

          @class MainWindow : public QMainWindow
          {
          Q_OBJECT

          public:
          bool TestActive;
          bool ProcessEvents;
          QEventLoop *EventLoopObj;

          QThread *TestThreadObj;
          TestClass *TestObj;
          
          RelayClass *RelayObj;
          
          ScopeClass *ScopeObj;
          
          MotorClass *MotorObj;
          
          explicit MainWindow(QWidget *parent = 0);
          ~MainWindow();
          
          void Initialize();
          void Uninitialize();
          

          public slots:
          void on_StartBtn_clicked();

          void SLOT_StopEventProcessing();
          

          signals:
          void SIGNAL_StartTest();

          };@

          @MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
          {
          EventLoopObj = new QEventLoop(parent);

          TestThreadObj = new QThread();
          TestObj = new TestClass();
          
          RelayObj = new RelayClass();
          
          ScopeObj = new ScopeClass();
          
          MotorObj = new MotorClass();
          

          }

          MainWindow::~MainWindow()
          {
          EventLoopObj->deleteLater();

          MotorObj->deleteLater();
          
          ScopeObj->deleteLater();
          
          RelayObj->deleteLater();
          
          TestThreadObj->deleteLater();
          TestObj->deleteLater();
          

          }

          void MainWindow::Initialize()
          {
          //START THREAD OBJs
          TestThreadObj->start();

          //MOVE OBJECTS TO THREADS
          TestObj->moveToThread(TestThreadObj);
          ScopeObj->moveToThread(TestThreadObj); 
          MotorObj->moveToThread(TestThreadObj); 
          RelayObj->moveToThread(TestThreadObj); 
          
          //SET TEST OBJ
          TestObj->Initialize();
          
          //SET RELAY OBJ
          RelayObj->setPort(ui->Relay_Com->text());
          RelayObj->Initialize();
          
          //SET SCOPE OBJ
          ScopeObj->Initialize();
          
          //SET MOTOR OBJ
          MotorObj->SetPort(ui->Motor_Com->text()); //Merge with Initialize
          MotorObj->Initialize();
          
          //CONNECT UI OBJ
          connect(this, SIGNAL(SIGNAL_StartTest()), TestObj,SLOT(StartTest())); 
          connect(TestObj, SIGNAL(TestingDone()), this, SLOT(SLOT_StopEventProcessing())); 
          
          //CONNECT RELAY OBJ
          connect(TestObj, SIGNAL(SIGNAL_AllRelaysOff()), RelayObj, SLOT(RelaysAllOff()));
          connect(TestObj, SIGNAL(SIGNAL_RelayOn(int)), RelayObj, SLOT(RelayOn(int)));
          
          //CONNECT SCOPE OBJ
          connect(TestObj, SIGNAL(SIGNAL_SCOPE_Initialize()), ScopeObj, SLOT(Initialize()));
          connect(TestObj, SIGNAL(SIGNAL_SCOPE_MeasureVavg()), ScopeObj, SLOT(TestVavg()));
          connect(TestObj, SIGNAL(SIGNAL_SCOPE_MeasureVpp()), ScopeObj, SLOT(TestVpp()));
          connect(TestObj, SIGNAL(SIGNAL_SCOPE_MeasureVrms()), ScopeObj, SLOT(TestVrms()));
          
          //CONNECT MOTOR  OBJECT
          connect(TestObj, SIGNAL(SIGNAL_RunMotor()), MotorObj, SLOT(RunMotor()));
          
          TestActive = true;
          ProcessEvents =true;
          

          }

          void MainWindow::Uninitialize()
          {
          MotorObj->Uninitialize();

          ScopeObj->Uninitialize();
          
          RelayObj->Uninitialize();
          
          TestObj->Uninitialize();
          
          TestThreadObj->quit();
          

          }

          void MainWindow::on_StartBtn_clicked()
          {
          Initialize();
          emit SIGNAL_StartTest();
          while(ProcessEvents == true)
          {
          EventLoopObj->processEvents();
          }
          Uninitialize();
          }

          void MainWindow::SLOT_StopEventProcessing()
          {
          ProcessEvents = false;
          }
          @

          Inside the MotorObj and RelayObj there are QSerialPort variables.
          QSerialPort* ComPort = new (QSerialPort);
          From what I have read and understand this is where things go wrong.
          The QSerialPorts Object seems to be running in the wrong thread.
          I Have also tried to move the ComPort Objects contained in both MotorObj and RelayObj to the TestThread. When I do so The application Freezes when I click on the Start Button @MotorObj->ComPort->moveToThread(TestThreadObj);@

          1 Reply Last reply
          0
          • A Offline
            A Offline
            andre
            wrote on last edited by
            #6

            I have not studied the complete code sample yet. But does it help if you just create your QSerialPort object with the parent in the first place? QObject::moveToThread also moves all child objects, so that should work. If moving QSerialPort keeps given trouble, I suggest you only create it after the move from within the right thread.

            1 Reply Last reply
            0
            • A Offline
              A Offline
              achmed
              wrote on last edited by
              #7

              Ok. I Will get back to you. Thanks for your help.

              1 Reply Last reply
              0
              • A Offline
                A Offline
                achmed
                wrote on last edited by
                #8

                Looks like there was noting wrong with my initial approch by moving the objects to a Vanilla QThread. I Have managed to traced down the problem a bit more. I Think the warnings are a bit misleading. Below is the code for the RelayObj. If I comment out the "relays->write()" lines the errors disappear. Also If I create other objects in a similar way in the RelayClass like I do with QSerialPort I don't get any errors at all. Meaning it must be something to do with QSerialPort and how it behaves in a Threaded environment.

                1 Reply Last reply
                0
                • A Offline
                  A Offline
                  achmed
                  wrote on last edited by
                  #9

                  @#include "relayclass.h"

                  RelayClass::RelayClass(QObject *parent) : QObject(parent)
                  {
                  relays = new (QSerialPort);
                  }

                  RelayClass::~RelayClass()
                  {
                  relays->deleteLater();
                  }

                  void RelayClass::Initialize()
                  {
                  relays->setPortName(COM);

                  if(relays->open(QIODevice::ReadWrite))
                  {
                      relays->setBaudRate(QSerialPort::Baud9600);
                      relays->setDataBits(QSerialPort::Data8);
                      relays->setParity(QSerialPort::NoParity);
                      relays->setStopBits(QSerialPort::OneStop);
                      relays->setFlowControl(QSerialPort::NoFlowControl);
                  }
                  

                  }

                  void RelayClass::Uninitialize()
                  {
                  //relays->close();
                  }

                  void RelayClass::RelaysAllOff()
                  {
                  relay_arr.clear();
                  relay_arr = "all_offx";
                  //relays->write(relay_arr); //Causes Error
                  relays->waitForBytesWritten(-1);
                  }

                  void RelayClass::RelayOn(int Ch_on)
                  {
                  relay_arr.clear();
                  relay_arr.setNum(Ch_on);
                  relay_arr.prepend("ch");
                  relay_arr.append("_onx");
                  //relays->write(relay_arr); //Causes Error
                  relays->waitForBytesWritten(-1);
                  }

                  void RelayClass::setPort(QString PORT)
                  {
                  COM = PORT;
                  }
                  @

                  1 Reply Last reply
                  0
                  • A Offline
                    A Offline
                    achmed
                    wrote on last edited by
                    #10

                    @#ifndef RELAYCLASS_H
                    #define RELAYCLASS_H

                    #include <QObject>
                    #include <QtSerialPort>
                    #include <QString>

                    #include "waitclass.h"

                    class RelayClass : public QObject
                    {
                    Q_OBJECT
                    public:
                    QString COM;
                    QByteArray relay_arr;
                    QSerialPort *relays;

                    WaitClass *WaitObj;
                    
                    explicit RelayClass(QObject *parent=0);
                    ~RelayClass();
                    
                    void Initialize();
                    void Uninitialize();
                    

                    public slots:
                    void RelaysAllOff();
                    void RelayOn(int Ch_on);
                    void setPort(QString PORT);
                    };

                    #endif // RELAYCLASS_H
                    @

                    1 Reply Last reply
                    0
                    • A Offline
                      A Offline
                      achmed
                      wrote on last edited by
                      #11

                      Looks like this article may have the answer to my problems.
                      "LINK":http://stackoverflow.com/questions/23559610/how-to-setup-qserialport-on-a-separate-thread

                      1 Reply Last reply
                      0
                      • A Offline
                        A Offline
                        achmed
                        wrote on last edited by
                        #12

                        Ok. Problem solved.
                        I Moved the QSerialPort variables to my main thread and now use Signals and Slots to send data to them. I'm not an expert on this, and just quoting what I have read. QSerialPort already provides you non-blocking mechanism for your GUI application. When moving QSeerial Port to another thread this somehow interferes with the way objects communicate between one another and that is where the errors are coming from. If anyone has some extra opinions on this or knows how to move a QSerialPort object into a separate thread, please do share.

                        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