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

passing signal between threads with Qvector as parameter

Scheduled Pinned Locked Moved Solved General and Desktop
13 Posts 5 Posters 1.1k 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 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