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. passing signal between threads with Qvector as parameter
QtWS25 Last Chance

passing signal between threads with Qvector as parameter

Scheduled Pinned Locked Moved Solved General and Desktop
13 Posts 5 Posters 1.0k 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.
  • D Offline
    D Offline
    Daddedebad
    wrote on last edited by Daddedebad
    #1

    Hey, I have an issue where I can pass a signal and get it right on the other end between threads, but this no longer works when I try to pass a Qvector with the signal as a parameter. Other variable is fine though, I can pass a Qstring without issue.

    Here is my code:

    h-files:

    // Main thread class
    class QtWidgetsApplication : public QWidget
    {
        Q_OBJECT
        QThread secondThread;
    public:
        secondThreadClass* secondClass = nullptr;
        QtWidgetsApplication(QWidget *parent = nullptr);
        ~QtWidgetsApplication();
    
    private:
        Ui::QtWidgetsApplicationClass ui;
    
    signals:
        void doWorkInSecondThread(const QString&, QVector<int>&);
    };
    
    // Second thread class
    class secondThreadClass :public inheritedParent
    {
    public:
        secondThreadClass();
    public slots:
        void sayHello(const QString& text, QVector<int>& dataSet);
    };
    
    // Inherited class
    class inheritedParent : public QObject
    {
        Q_OBJECT
    };
    

    c-files:

    //Main thread class
    QtWidgetsApplication::QtWidgetsApplication(QWidget* parent)
        : QWidget(parent)
    {
        QVector<int> dataSet = { 0,3,1,2 };
        ui.setupUi(this);
        secondClass = new secondThreadClass();
    
        secondClass->moveToThread(&secondThread);
        connect(&secondThread, &QThread::finished, secondClass, &QObject::deleteLater);
        connect(this, &QtWidgetsApplication::doWorkInSecondThread, secondClass, &secondThreadClass::sayHello);
    
        secondThread.start();
    
        emit doWorkInSecondThread(QString("Hello"), dataSet);
    }
    
    QtWidgetsApplication::~QtWidgetsApplication()
    {}
    
    // Second thread class
    secondThreadClass::secondThreadClass(){}
    
    void secondThreadClass::sayHello(const QString& text, QVector<int>& dataSet)
    {
        print(text);
        return;
    }
    

    InheritedParent is empty. It is in this example just to show exactly what I did. This is from debugging another code where I made my structure like this.

    If I remove the QVector parameter, the code works and text "Hello" is passed between the threads and executed in secondThreadClass.

    I am thankful for all the help I can get!

    PS. I am using QT 5.15.2

    jsulmJ B JonBJ 3 Replies Last reply
    0
    • D Daddedebad

      Hey, I have an issue where I can pass a signal and get it right on the other end between threads, but this no longer works when I try to pass a Qvector with the signal as a parameter. Other variable is fine though, I can pass a Qstring without issue.

      Here is my code:

      h-files:

      // Main thread class
      class QtWidgetsApplication : public QWidget
      {
          Q_OBJECT
          QThread secondThread;
      public:
          secondThreadClass* secondClass = nullptr;
          QtWidgetsApplication(QWidget *parent = nullptr);
          ~QtWidgetsApplication();
      
      private:
          Ui::QtWidgetsApplicationClass ui;
      
      signals:
          void doWorkInSecondThread(const QString&, QVector<int>&);
      };
      
      // Second thread class
      class secondThreadClass :public inheritedParent
      {
      public:
          secondThreadClass();
      public slots:
          void sayHello(const QString& text, QVector<int>& dataSet);
      };
      
      // Inherited class
      class inheritedParent : public QObject
      {
          Q_OBJECT
      };
      

      c-files:

      //Main thread class
      QtWidgetsApplication::QtWidgetsApplication(QWidget* parent)
          : QWidget(parent)
      {
          QVector<int> dataSet = { 0,3,1,2 };
          ui.setupUi(this);
          secondClass = new secondThreadClass();
      
          secondClass->moveToThread(&secondThread);
          connect(&secondThread, &QThread::finished, secondClass, &QObject::deleteLater);
          connect(this, &QtWidgetsApplication::doWorkInSecondThread, secondClass, &secondThreadClass::sayHello);
      
          secondThread.start();
      
          emit doWorkInSecondThread(QString("Hello"), dataSet);
      }
      
      QtWidgetsApplication::~QtWidgetsApplication()
      {}
      
      // Second thread class
      secondThreadClass::secondThreadClass(){}
      
      void secondThreadClass::sayHello(const QString& text, QVector<int>& dataSet)
      {
          print(text);
          return;
      }
      

      InheritedParent is empty. It is in this example just to show exactly what I did. This is from debugging another code where I made my structure like this.

      If I remove the QVector parameter, the code works and text "Hello" is passed between the threads and executed in secondThreadClass.

      I am thankful for all the help I can get!

      PS. I am using QT 5.15.2

      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by jsulm
      #2

      @Daddedebad said in passing signal between threads with Qvector as parameter:

      but this no longer works when I try to pass a Qvector with the signal as a parameter

      What exactly does not work? What happens?
      Does the slot have same parameters?

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • D Daddedebad

        Hey, I have an issue where I can pass a signal and get it right on the other end between threads, but this no longer works when I try to pass a Qvector with the signal as a parameter. Other variable is fine though, I can pass a Qstring without issue.

        Here is my code:

        h-files:

        // Main thread class
        class QtWidgetsApplication : public QWidget
        {
            Q_OBJECT
            QThread secondThread;
        public:
            secondThreadClass* secondClass = nullptr;
            QtWidgetsApplication(QWidget *parent = nullptr);
            ~QtWidgetsApplication();
        
        private:
            Ui::QtWidgetsApplicationClass ui;
        
        signals:
            void doWorkInSecondThread(const QString&, QVector<int>&);
        };
        
        // Second thread class
        class secondThreadClass :public inheritedParent
        {
        public:
            secondThreadClass();
        public slots:
            void sayHello(const QString& text, QVector<int>& dataSet);
        };
        
        // Inherited class
        class inheritedParent : public QObject
        {
            Q_OBJECT
        };
        

        c-files:

        //Main thread class
        QtWidgetsApplication::QtWidgetsApplication(QWidget* parent)
            : QWidget(parent)
        {
            QVector<int> dataSet = { 0,3,1,2 };
            ui.setupUi(this);
            secondClass = new secondThreadClass();
        
            secondClass->moveToThread(&secondThread);
            connect(&secondThread, &QThread::finished, secondClass, &QObject::deleteLater);
            connect(this, &QtWidgetsApplication::doWorkInSecondThread, secondClass, &secondThreadClass::sayHello);
        
            secondThread.start();
        
            emit doWorkInSecondThread(QString("Hello"), dataSet);
        }
        
        QtWidgetsApplication::~QtWidgetsApplication()
        {}
        
        // Second thread class
        secondThreadClass::secondThreadClass(){}
        
        void secondThreadClass::sayHello(const QString& text, QVector<int>& dataSet)
        {
            print(text);
            return;
        }
        

        InheritedParent is empty. It is in this example just to show exactly what I did. This is from debugging another code where I made my structure like this.

        If I remove the QVector parameter, the code works and text "Hello" is passed between the threads and executed in secondThreadClass.

        I am thankful for all the help I can get!

        PS. I am using QT 5.15.2

        B Offline
        B Offline
        Bonnie
        wrote on last edited by Bonnie
        #3

        @Daddedebad Take a look at your application output, it should print some hint when it tries to connect the signal but fails.
        I think QVector<int> needs to be registered by qRegisterMetaType or something like that.
        For your reference: https://doc.qt.io/qt-6/custom-types.html#creating-and-destroying-custom-objects

        D 1 Reply Last reply
        2
        • D Daddedebad

          Hey, I have an issue where I can pass a signal and get it right on the other end between threads, but this no longer works when I try to pass a Qvector with the signal as a parameter. Other variable is fine though, I can pass a Qstring without issue.

          Here is my code:

          h-files:

          // Main thread class
          class QtWidgetsApplication : public QWidget
          {
              Q_OBJECT
              QThread secondThread;
          public:
              secondThreadClass* secondClass = nullptr;
              QtWidgetsApplication(QWidget *parent = nullptr);
              ~QtWidgetsApplication();
          
          private:
              Ui::QtWidgetsApplicationClass ui;
          
          signals:
              void doWorkInSecondThread(const QString&, QVector<int>&);
          };
          
          // Second thread class
          class secondThreadClass :public inheritedParent
          {
          public:
              secondThreadClass();
          public slots:
              void sayHello(const QString& text, QVector<int>& dataSet);
          };
          
          // Inherited class
          class inheritedParent : public QObject
          {
              Q_OBJECT
          };
          

          c-files:

          //Main thread class
          QtWidgetsApplication::QtWidgetsApplication(QWidget* parent)
              : QWidget(parent)
          {
              QVector<int> dataSet = { 0,3,1,2 };
              ui.setupUi(this);
              secondClass = new secondThreadClass();
          
              secondClass->moveToThread(&secondThread);
              connect(&secondThread, &QThread::finished, secondClass, &QObject::deleteLater);
              connect(this, &QtWidgetsApplication::doWorkInSecondThread, secondClass, &secondThreadClass::sayHello);
          
              secondThread.start();
          
              emit doWorkInSecondThread(QString("Hello"), dataSet);
          }
          
          QtWidgetsApplication::~QtWidgetsApplication()
          {}
          
          // Second thread class
          secondThreadClass::secondThreadClass(){}
          
          void secondThreadClass::sayHello(const QString& text, QVector<int>& dataSet)
          {
              print(text);
              return;
          }
          

          InheritedParent is empty. It is in this example just to show exactly what I did. This is from debugging another code where I made my structure like this.

          If I remove the QVector parameter, the code works and text "Hello" is passed between the threads and executed in secondThreadClass.

          I am thankful for all the help I can get!

          PS. I am using QT 5.15.2

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by
          #4

          @Daddedebad
          As @Bonnie says qRegisterMetaType.

          A separate point for your own benefit. I think you should consider making the signal/slot parameter be const QVector<int>& dataSet. Passing across threads (queued connection) will copy the QVector in either case, but the const will remind you that you cannot alter the original QVector in the other thread. [Expert correct me if I am wrong here, but seems useful to me.]

          1 Reply Last reply
          3
          • B Bonnie

            @Daddedebad Take a look at your application output, it should print some hint when it tries to connect the signal but fails.
            I think QVector<int> needs to be registered by qRegisterMetaType or something like that.
            For your reference: https://doc.qt.io/qt-6/custom-types.html#creating-and-destroying-custom-objects

            D Offline
            D Offline
            Daddedebad
            wrote on last edited by Daddedebad
            #5

            @Bonnie I think you are right, this is what the console says:

            QObject::connect: Cannot queue arguments of type 'QVector<int>&'
            (Make sure 'QVector<int>&' is registered using qRegisterMetaType().)

            I tried registering using qRegisterMetaType(QVector<int>) but got the same output. It needs the reference specifically. However, I cannot register QVector<int>& because then it doesn't compile.

            my main.cpp code now:

            #include "QtWidgetsApplication2.h"
            #include <QtWidgets/QApplication>

            int main(int argc, char *argv[])
            {
                QApplication a(argc, argv);
                qRegisterMetaType<QVector<int>&>();
            
                QtWidgetsApplication2 w;
                w.show();
                return a.exec();
            }
            

            Gives errors:

            Severity	Code	Description	Project	File	Line	Suppression State
            Error	C2338	Type is not registered, please use the Q_DECLARE_METATYPE macro to make it known to Qt's meta-object system	QtWidgetsApplication	X:\X\X\X\QtCore\qmetatype.h	1916	
            
            Severity	Code	Description	Project	File	Line	Suppression State
            Error	C2039	'qt_metatype_id': is not a member of 'QMetaTypeId2<T>'	QtWidgetsApplication	X:\X\X\X\X\QtCore\qmetatype.h	1917	
            
            Severity	Code	Description	Project	File	Line	Suppression State
            Error	C3861	'qt_metatype_id': identifier not found	QtWidgetsApplication	X:\X\X\X\X\QtCore\qmetatype.h	1917
            

            I'm trying to find how to do it, but it seems that references are tricky to register?

            Also I'm using QT 5.15.2, so far I don't think it matters but I will add it to the main post.

            jsulmJ 1 Reply Last reply
            0
            • D Daddedebad

              @Bonnie I think you are right, this is what the console says:

              QObject::connect: Cannot queue arguments of type 'QVector<int>&'
              (Make sure 'QVector<int>&' is registered using qRegisterMetaType().)

              I tried registering using qRegisterMetaType(QVector<int>) but got the same output. It needs the reference specifically. However, I cannot register QVector<int>& because then it doesn't compile.

              my main.cpp code now:

              #include "QtWidgetsApplication2.h"
              #include <QtWidgets/QApplication>

              int main(int argc, char *argv[])
              {
                  QApplication a(argc, argv);
                  qRegisterMetaType<QVector<int>&>();
              
                  QtWidgetsApplication2 w;
                  w.show();
                  return a.exec();
              }
              

              Gives errors:

              Severity	Code	Description	Project	File	Line	Suppression State
              Error	C2338	Type is not registered, please use the Q_DECLARE_METATYPE macro to make it known to Qt's meta-object system	QtWidgetsApplication	X:\X\X\X\QtCore\qmetatype.h	1916	
              
              Severity	Code	Description	Project	File	Line	Suppression State
              Error	C2039	'qt_metatype_id': is not a member of 'QMetaTypeId2<T>'	QtWidgetsApplication	X:\X\X\X\X\QtCore\qmetatype.h	1917	
              
              Severity	Code	Description	Project	File	Line	Suppression State
              Error	C3861	'qt_metatype_id': identifier not found	QtWidgetsApplication	X:\X\X\X\X\QtCore\qmetatype.h	1917
              

              I'm trying to find how to do it, but it seems that references are tricky to register?

              Also I'm using QT 5.15.2, so far I don't think it matters but I will add it to the main post.

              jsulmJ Offline
              jsulmJ Offline
              jsulm
              Lifetime Qt Champion
              wrote on last edited by
              #6

              @Daddedebad Don't register references! Just register QVector<int>.

              https://forum.qt.io/topic/113070/qt-code-of-conduct

              D 1 Reply Last reply
              1
              • jsulmJ jsulm

                @Daddedebad Don't register references! Just register QVector<int>.

                D Offline
                D Offline
                Daddedebad
                wrote on last edited by
                #7

                @jsulm registering without the reference like this:

                int main(int argc, char *argv[])
                {
                    QApplication a(argc, argv);
                    qRegisterMetaType<QVector<int>>();
                
                    QtWidgetsApplication2 w;
                    w.show();
                    return a.exec();
                }
                

                Gives the console output:

                QObject::connect: Cannot queue arguments of type 'QVector<int>&'
                (Make sure 'QVector<int>&' is registered using qRegisterMetaType().)

                So if I register without the reference, what should the next step be?

                JonBJ 1 Reply Last reply
                0
                • D Daddedebad

                  @jsulm registering without the reference like this:

                  int main(int argc, char *argv[])
                  {
                      QApplication a(argc, argv);
                      qRegisterMetaType<QVector<int>>();
                  
                      QtWidgetsApplication2 w;
                      w.show();
                      return a.exec();
                  }
                  

                  Gives the console output:

                  QObject::connect: Cannot queue arguments of type 'QVector<int>&'
                  (Make sure 'QVector<int>&' is registered using qRegisterMetaType().)

                  So if I register without the reference, what should the next step be?

                  JonBJ Offline
                  JonBJ Offline
                  JonB
                  wrote on last edited by JonB
                  #8

                  @Daddedebad said in passing signal between threads with Qvector as parameter:

                  QObject::connect: Cannot queue arguments of type 'QVector<int>&'

                  I suggested you prepend const. If you do so does that affect this error? I'm not sure that you can pass a non-const reference as an argument in signals and slots when using a queued connection. You might also not bother with the & reference at all, since as I said it gets copied for queued anyway.

                  D Christian EhrlicherC 2 Replies Last reply
                  3
                  • JonBJ JonB

                    @Daddedebad said in passing signal between threads with Qvector as parameter:

                    QObject::connect: Cannot queue arguments of type 'QVector<int>&'

                    I suggested you prepend const. If you do so does that affect this error? I'm not sure that you can pass a non-const reference as an argument in signals and slots when using a queued connection. You might also not bother with the & reference at all, since as I said it gets copied for queued anyway.

                    D Offline
                    D Offline
                    Daddedebad
                    wrote on last edited by
                    #9

                    @JonB Yes that seemed to solve it! Thank you! I added const.

                    @JonB said in passing signal between threads with Qvector as parameter:

                    You might also not bother with the & reference at all, since as I said it gets copied for queued anyway.

                    Aha ok, I don't think I need it for my program, but that means I cannot pass references between threads doing this?

                    jsulmJ 1 Reply Last reply
                    0
                    • D Daddedebad

                      @JonB Yes that seemed to solve it! Thank you! I added const.

                      @JonB said in passing signal between threads with Qvector as parameter:

                      You might also not bother with the & reference at all, since as I said it gets copied for queued anyway.

                      Aha ok, I don't think I need it for my program, but that means I cannot pass references between threads doing this?

                      jsulmJ Offline
                      jsulmJ Offline
                      jsulm
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      @Daddedebad said in passing signal between threads with Qvector as parameter:

                      I cannot pass references between threads doing this?

                      No, parameters are copied across different threads (to avoid problems with musltithreading).

                      https://forum.qt.io/topic/113070/qt-code-of-conduct

                      1 Reply Last reply
                      2
                      • JonBJ JonB

                        @Daddedebad said in passing signal between threads with Qvector as parameter:

                        QObject::connect: Cannot queue arguments of type 'QVector<int>&'

                        I suggested you prepend const. If you do so does that affect this error? I'm not sure that you can pass a non-const reference as an argument in signals and slots when using a queued connection. You might also not bother with the & reference at all, since as I said it gets copied for queued anyway.

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

                        @JonB said in passing signal between threads with Qvector as parameter:

                        I'm not sure that you can pass a non-const reference as an argument in signals and slots when using a queued connection.

                        You can't - how should it work if you would be able to? And this was the initial problem here.

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

                        JonBJ 1 Reply Last reply
                        0
                        • Christian EhrlicherC Christian Ehrlicher

                          @JonB said in passing signal between threads with Qvector as parameter:

                          I'm not sure that you can pass a non-const reference as an argument in signals and slots when using a queued connection.

                          You can't - how should it work if you would be able to? And this was the initial problem here.

                          JonBJ Offline
                          JonBJ Offline
                          JonB
                          wrote on last edited by JonB
                          #12

                          @Christian-Ehrlicher
                          Yes, I said from the start that was the case, it would not work as you would expect. I was suggesting that the error message QObject::connect: Cannot queue arguments of type 'QVector<int>&' might be because connect() refuses to accept them for queueing, but would allow if const.

                          Christian EhrlicherC 1 Reply Last reply
                          0
                          • JonBJ JonB

                            @Christian-Ehrlicher
                            Yes, I said from the start that was the case, it would not work as you would expect. I was suggesting that the error message QObject::connect: Cannot queue arguments of type 'QVector<int>&' might be because connect() refuses to accept them for queueing, but would allow if const.

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

                            @JonB said in passing signal between threads with Qvector as parameter:

                            might be because connect() refuses to accept them for queueing.

                            correct

                            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
                            2
                            • D Daddedebad 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