Problem with running timer in another thread
-
@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()
-
I thinking why we are talking about more than one thread? And why the error applies other thread? Since both CctalkDevice and MyCcTalkApp class are the same thread.... Only SerialWorker works in own thread which one is launched by CctalkLinkController .
The polling timer is in CctalkDevice, so what is the problem ? -
I thinking why we are talking about more than one thread? And why the error applies other thread? Since both CctalkDevice and MyCcTalkApp class are the same thread.... Only SerialWorker works in own thread which one is launched by CctalkLinkController .
The polling timer is in CctalkDevice, so what is the problem ?@Damian7546 print out thread ids on the screen in the constructor and in this function. Check out why they are different.
-
@Damian7546 print out thread ids on the screen in the constructor and in this function. Check out why they are different.
@hskoglund without changes.
QML debugging is enabled. Only use this in a safe environment.
ThreadID SerialWorker: 0x7cb34f9b27c0
ThreadID CctalkLinkController: 0x7cb34f9b27c0
ThreadID CctalkDevice: 0x7cb34f9b27c0
ThreadID MyCcTalkApp: 0x7cb34f9b27c0
LogMessgae: "* Coin acceptor configured device: /dev/ttyUSB0"
LogMessgae: "* Opening port "/dev/ttyUSB0"."
LogMessgae: "Requested device state change from ShutDown to: Initialized"
ThreadID in startTimer() 0x71df85200640
LogMessgae: "* Port "/dev/ttyUSB0" opened."
LogMessgae: "> ccTalk request: SimplePoll, address: 2, data: (empty)"
QMetaObject::invokeMethod: No such method qtcc::CctalkDevice::startTimer()
LogMessgae: "> Request: 020001feff"
LogMessgae: "< Full response: 020001feff01000200fd"
LogMessgae: "< ccTalk response from address 2, data: (empty)"
LogMessgae: "* Device is alive (answered to simple poll)"
QObject::startTimer: Timers cannot be started from another thread*now I don't understand anything, why only the startTimer is on other thread?
-
@hskoglund without changes.
QML debugging is enabled. Only use this in a safe environment.
ThreadID SerialWorker: 0x7cb34f9b27c0
ThreadID CctalkLinkController: 0x7cb34f9b27c0
ThreadID CctalkDevice: 0x7cb34f9b27c0
ThreadID MyCcTalkApp: 0x7cb34f9b27c0
LogMessgae: "* Coin acceptor configured device: /dev/ttyUSB0"
LogMessgae: "* Opening port "/dev/ttyUSB0"."
LogMessgae: "Requested device state change from ShutDown to: Initialized"
ThreadID in startTimer() 0x71df85200640
LogMessgae: "* Port "/dev/ttyUSB0" opened."
LogMessgae: "> ccTalk request: SimplePoll, address: 2, data: (empty)"
QMetaObject::invokeMethod: No such method qtcc::CctalkDevice::startTimer()
LogMessgae: "> Request: 020001feff"
LogMessgae: "< Full response: 020001feff01000200fd"
LogMessgae: "< ccTalk response from address 2, data: (empty)"
LogMessgae: "* Device is alive (answered to simple poll)"
QObject::startTimer: Timers cannot be started from another thread*now I don't understand anything, why only the startTimer is on other thread?
@Damian7546 move startTimer() to public slots:
public slots:
void startTimer();if ( QThread::currentThread() != thread() ) { metaObject()->invokeMethod( this, "startTimer", Qt::QueuedConnection ); return; }If you have stop func for timer, you may need to do the same thing. The code above works in my app.
-
@Damian7546 move startTimer() to public slots:
public slots:
void startTimer();if ( QThread::currentThread() != thread() ) { metaObject()->invokeMethod( this, "startTimer", Qt::QueuedConnection ); return; }If you have stop func for timer, you may need to do the same thing. The code above works in my app.
@JoeCFD something is starting to work...
-
@JoeCFD something is starting to work...
@Damian7546 Have fun.
-
@Damian7546 Have fun.
@hskoglund said in Problem with running timer in another thread:
Ah, I see in your cctalk_device.h file, startTimer() is declared under protected:
try moving it under slots: (like your function void timerIteration();)Problem is more complicated then can I thought, probably not related with startTimer() function .
I totally remove calling startTimer() from my project and still have the same error :QML debugging is enabled. Only use this in a safe environment. ThreadID SerialWorker: 0x79e36d8867c0 ThreadID CctalkLinkController: 0x79e36d8867c0 ThreadID CctalkDevice: 0x79e36d8867c0 Using "/home/developer/.config/CCtalkProj.ini" as a user-specific settings file ThreadID MyCcTalkApp: 0x79e36d8867c0 "* Coin acceptor configured device: /dev/ttyUSB0" "* Opening port \"/dev/ttyUSB0\"." "Requested device state change from ShutDown to: Initialized" test test test "* Port \"/dev/ttyUSB0\" opened." "> ccTalk request: SimplePoll, address: 2, data: (empty)" "> Request: 020001feff" "< Full response: 020001feff01000200fd" "< ccTalk response from address 2, data: (empty)" "* Device is alive (answered to simple poll)" QObject::startTimer: Timers cannot be started from another threadBelow I publish code wihich I try run:
[https://github.com/ienecode/cctalk.git](link url) -
Still the same problem as originally.
your 'serial_port_' is not moved with move ToThread QSerialPort uses internally QTimer thats why you see the message.
-
@J-Hilk So, how can I fix this code ? Can you give me tips ?
-
Pass the correct parent to your 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)} {