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
Forum Updated to NodeBB v4.3 + New Features

passing signal between threads with Qvector as parameter

Scheduled Pinned Locked Moved Solved General and Desktop
13 Posts 5 Posters 1.1k 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.
  • D Daddedebad
    20 Apr 2023, 07:55

    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

    J Offline
    J Offline
    jsulm
    Lifetime Qt Champion
    wrote on 20 Apr 2023, 08:05 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
      20 Apr 2023, 07:55

      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 20 Apr 2023, 08:11 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 20 Apr 2023, 09:09
      2
      • D Daddedebad
        20 Apr 2023, 07:55

        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

        J Offline
        J Offline
        JonB
        wrote on 20 Apr 2023, 08:23 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
          20 Apr 2023, 08:11

          @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 20 Apr 2023, 09:09 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.

          J 1 Reply Last reply 20 Apr 2023, 09:10
          0
          • D Daddedebad
            20 Apr 2023, 09:09

            @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.

            J Offline
            J Offline
            jsulm
            Lifetime Qt Champion
            wrote on 20 Apr 2023, 09:10 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 20 Apr 2023, 09:12
            1
            • J jsulm
              20 Apr 2023, 09:10

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

              D Offline
              D Offline
              Daddedebad
              wrote on 20 Apr 2023, 09:12 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?

              J 1 Reply Last reply 20 Apr 2023, 09:25
              0
              • D Daddedebad
                20 Apr 2023, 09:12

                @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?

                J Offline
                J Offline
                JonB
                wrote on 20 Apr 2023, 09:25 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 C 2 Replies Last reply 20 Apr 2023, 09:30
                3
                • J JonB
                  20 Apr 2023, 09:25

                  @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 20 Apr 2023, 09:30 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?

                  J 1 Reply Last reply 20 Apr 2023, 11:22
                  0
                  • D Daddedebad
                    20 Apr 2023, 09:30

                    @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?

                    J Offline
                    J Offline
                    jsulm
                    Lifetime Qt Champion
                    wrote on 20 Apr 2023, 11:22 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
                    • J JonB
                      20 Apr 2023, 09:25

                      @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.

                      C Offline
                      C Offline
                      Christian Ehrlicher
                      Lifetime Qt Champion
                      wrote on 20 Apr 2023, 15:31 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

                      J 1 Reply Last reply 20 Apr 2023, 15:35
                      0
                      • C Christian Ehrlicher
                        20 Apr 2023, 15:31

                        @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.

                        J Offline
                        J Offline
                        JonB
                        wrote on 20 Apr 2023, 15:35 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.

                        C 1 Reply Last reply 20 Apr 2023, 15:35
                        0
                        • J JonB
                          20 Apr 2023, 15:35

                          @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.

                          C Offline
                          C Offline
                          Christian Ehrlicher
                          Lifetime Qt Champion
                          wrote on 20 Apr 2023, 15:35 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 27 Nov 2023, 12:10

                          11/13

                          20 Apr 2023, 15:31

                          • Login

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