passing signal between threads with Qvector as parameter
-
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
-
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
@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? -
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
@Daddedebad Take a look at your application output, it should print some hint when it tries to connect the signal but fails.
I thinkQVector<int>
needs to be registered byqRegisterMetaType
or something like that.
For your reference: https://doc.qt.io/qt-6/custom-types.html#creating-and-destroying-custom-objects -
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
@Daddedebad
As @Bonnie saysqRegisterMetaType
.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 theQVector
in either case, but theconst
will remind you that you cannot alter the originalQVector
in the other thread. [Expert correct me if I am wrong here, but seems useful to me.] -
@Daddedebad Take a look at your application output, it should print some hint when it tries to connect the signal but fails.
I thinkQVector<int>
needs to be registered byqRegisterMetaType
or something like that.
For your reference: https://doc.qt.io/qt-6/custom-types.html#creating-and-destroying-custom-objects@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.
-
@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.
@Daddedebad Don't register references! Just register QVector<int>.
-
@Daddedebad Don't register references! Just register QVector<int>.
@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?
-
@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?
@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. -
@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.@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?
-
@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?
@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).
-
@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.@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.
-
@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.
@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 messageQObject::connect: Cannot queue arguments of type 'QVector<int>&'
might be becauseconnect()
refuses to accept them for queueing, but would allow ifconst
. -
@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 messageQObject::connect: Cannot queue arguments of type 'QVector<int>&'
might be becauseconnect()
refuses to accept them for queueing, but would allow ifconst
.@JonB said in passing signal between threads with Qvector as parameter:
might be because connect() refuses to accept them for queueing.
correct
-