Problem with running timer in another thread
-
To my project I added protocol implementation published in below:
[https://github.com/ashaduri/qt-cctalk/tree/main/cctalk](link url)I not use included test_gui only added to my class.
I do not understand why when the polling timer try start I get error :QObject::startTimer: Timers cannot be started from another thread
I am talking about 78 line in below file:
[https://github.com/ashaduri/qt-cctalk/blob/main/cctalk/cctalk_device.cpp](link url)Anyone can help me how run this timer ?
-
@J-Hilk So, how can I fix this code ? Can you give me tips ?
- Fix your constructor of your QObject based worker: More of a principal matter in this case
class SerialWorker : public QObject { Q_OBJECT public: /// Constructor SerialWorker(); ...->... class SerialWorker : public QObject { Q_OBJECT public: /// Constructor explicit SerialWorker(QObbject *parent = nullptr); ..... SerialWorker::SerialWorker() { ...->... SerialWorker::SerialWorker(QObject*parent) : QObject(parent) {- Drop the scoped pointer, you're trying to be fancy when there's no need for it and it's causing trouble
QScopedPointer<QSerialPort> serial_port_; ...-> QSerialPort * const serial_port_; //Raw dogging the serial port, hell ya- Init the QSerialport correctly:
SerialWorker::SerialWorker(QObject*parent) : QObject(parent), serial_port_{new QSerialPort(this)} { -
Hi,
Your timer is a class member and is thus created in the thread where your object is created in and not moved to the new thread.
-
To my project I added protocol implementation published in below:
[https://github.com/ashaduri/qt-cctalk/tree/main/cctalk](link url)I not use included test_gui only added to my class.
I do not understand why when the polling timer try start I get error :QObject::startTimer: Timers cannot be started from another thread
I am talking about 78 line in below file:
[https://github.com/ashaduri/qt-cctalk/blob/main/cctalk/cctalk_device.cpp](link url)Anyone can help me how run this timer ?
@Damian7546 said in Problem with running timer in another thread:
Anyone can help me how run this timer ?
Allocate the timer on the heap and make it a child of the class it is in.
Then it will change its thread-affinity with the parent. -
Hi,
Your timer is a class member and is thus created in the thread where your object is created in and not moved to the new thread.
@SGaist
So how solution this problem ? I try use moveToThread no result -
@Damian7546 said in Problem with running timer in another thread:
Anyone can help me how run this timer ?
Allocate the timer on the heap and make it a child of the class it is in.
Then it will change its thread-affinity with the parent.@Pl45m4 I should change only event_timer_ or whole function CctalkDevice::startTimer() ?
Can you explain me? -
@Pl45m4 I should change only event_timer_ or whole function CctalkDevice::startTimer() ?
Can you explain me?@Damian7546 said in Problem with running timer in another thread:
I should change only event_timer_ or whole function CctalkDevice::startTimer() ?
@Pl45m4 said in Problem with running timer in another thread:
Allocate the timer on the heap and make it a child of the class it is in.
This is everything you have to do and the error/warning should be gone.
No need to change the function. -
@Damian7546 said in Problem with running timer in another thread:
I should change only event_timer_ or whole function CctalkDevice::startTimer() ?
@Pl45m4 said in Problem with running timer in another thread:
Allocate the timer on the heap and make it a child of the class it is in.
This is everything you have to do and the error/warning should be gone.
No need to change the function.@Pl45m4 In cctalk_device.h I changed
QTimer event_timer_;to
QTimer *event_timer_; ,next in CctalkDevice() constructor I added
event_timer_ = new QTimer(this);and enought ?
-
@Pl45m4 In cctalk_device.h I changed
QTimer event_timer_;to
QTimer *event_timer_; ,next in CctalkDevice() constructor I added
event_timer_ = new QTimer(this);and enought ?
@Damian7546 said in Problem with running timer in another thread:
and enough ?
When there is no more error, yes.
Does it work now?
-
@Damian7546 said in Problem with running timer in another thread:
and enough ?
When there is no more error, yes.
Does it work now?
@Pl45m4 No, it still the same error : QObject::startTimer: Timers cannot be started from another thread
-
@Damian7546 said in Problem with running timer in another thread:
Anyone can help me how run this timer ?
Allocate the timer on the heap and make it a child of the class it is in.
Then it will change its thread-affinity with the parent. -
@Pl45m4 In cctalk_device.h I changed
QTimer event_timer_;to
QTimer *event_timer_; ,next in CctalkDevice() constructor I added
event_timer_ = new QTimer(this);and enought ?
@Damian7546 Maybe try to add the following code into the func
if ( QThread::currentThread() != thread() ) { metaObject()->invokeMethod( this, "startTimer()", Qt::QueuedConnection ); return; }Make startTimer() to be a slot.
-
I know :)
Haven't checked the complete repository where and how everything is put together.But yeah,
event_timer.setParent(this);might also work.
-
@Pl45m4 In cctalk_device.h I changed
QTimer event_timer_;to
QTimer *event_timer_; ,next in CctalkDevice() constructor I added
event_timer_ = new QTimer(this);and enought ?
@Damian7546 said in Problem with running timer in another thread:
next in CctalkDevice() constructor I added
Don't do this in the constructor, do it in the method which is actually executed in the other thread.
-
@Pl45m4 that's a bad idea: this will trigger a double deletion. One when the parent is deleted and the second when the object goes out of scope.
@SGaist said in Problem with running timer in another thread:
that's a bad idea: this will trigger a double deletion
Oh my... that's why I initially thought of heap allocation and then using the parent-child architecture :D
@jsulm said in Problem with running timer in another thread:
Don't do this in the constructor, do it in the method which is actually executed in the other thread.
But when creating the timer on the heap and as child of the containing class in the contructor... if you then move the
ccDeviceobject, the timer (= child ofccDevice) is also moved, right?!@JoeCFD said in Problem with running timer in another thread:
Allocating the timer on the heap or stack should not matter.
So this doesn't matter in technical terms as the timer can/should be allocated on the stack, however when you want to use the parent-child relation to move the object to another thread, it does matter to avoid double deletion
-
I know :)
Haven't checked the complete repository where and how everything is put together.But yeah,
event_timer.setParent(this);might also work.
@Pl45m4 It doesn't work, still the same.
-
@Damian7546 Maybe try to add the following code into the func
if ( QThread::currentThread() != thread() ) { metaObject()->invokeMethod( this, "startTimer()", Qt::QueuedConnection ); return; }Make startTimer() to be a slot.
@JoeCFD said in Problem with running timer in another thread:
@Damian7546 Maybe try to add the following code into the func
if ( QThread::currentThread() != thread() ) { metaObject()->invokeMethod( this, "startTimer()", Qt::QueuedConnection ); return; }Make startTimer() to be a slot.
This one , still not working
QMetaObject::invokeMethod: No such method qtcc::CctalkDevice::startTimer()() -
Hi, try without the parentheses, like this:
...
metaObject()->invokeMethod( this, "startTimer", Qt::QueuedConnection );
...still the same QMetaObject::invokeMethod: No such method qtcc::CctalkDevice::startTimer()