Camera class in QThread
-
Hi,
I woluld like to implement the Camera class in a separate thread to be able to independently retrieve data from a device and process it in the run() method. Unfortunately, when calling the run() method, the code gets stuck in a loop and won't come out. As a result, I cannot stop the camera with the stop() method. How could I fix that?
camera.h:
class Camera : public QThread { Q_OBJECT public: Camera(); ~Camera() {} void run(); void stop() { camera_running = false; } private: rs2::config cfg; rs2::pipeline pipe; rs2::frameset frames; bool camera_running; signals: void FrameReady(rs2::depth_frame frame); };
camera.cpp:
Camera::Camera() { camera_running = true; cfg.enable_stream(RS2_STREAM_DEPTH, CAMERA::RESOLUTION::DEPTH_WIDTH, CAMERA::RESOLUTION::DEPTH_HIGHT, RS2_FORMAT_Z16, CAMERA::FPS); pipe.start(cfg); } void Camera::run() { while(!this->isInterruptionRequested()) { try{ frames = pipe.wait_for_frames(); rs2::depth_frame depth = frames.get_depth_frame(); emit FrameReady(depth); } catch(const rs2::error& e) { std::cout << "ERROR: " << e.get_failed_function() << "(" <<e.get_failed_args() <<") "<<e.what()<<std::endl; } } }
main.cpp:
QThread cameraThread; Camera *camera = new Camera(); QObject::connect(camera, &Camera::FrameReady, mqttClient, &MqttClient::sendFrame); camera->moveToThread(&cameraThread); camera->run(); qDebug()<<"Started"; //Will not be done camera->stop(); //Will not be done qDebug()<<"Stopped"; //Will not be done
-
I think the problem is that you call run directly from your GUI thread - this is a simple (blocking) call, not the start of a new thread. You should call start() on your camera object, I guess.
Edit: Your have two QThread objects - cameraThread and camera (which is derived from QThread) why? You mix the two options to use QThread (moving a worker object to QThread or reimplementing QThread::run(). ) -
@Creatorczyk Since you don't start the thread anywhere nothing happens.
-
@Christian-Ehrlicher I change code in main.cpp to:
QThread cameraThread; Camera *camera = new Camera(); QObject::connect(camera, &Camera::FrameReady, mqttClient, &MqttClient::sendFrame); camera->moveToThread(&cameraThread); cameraThread.start(); camera->run(); qDebug()<<"Started"; //Will not be done camera->stop(); //Will not be done qDebug()<<"Stopped"; //Will not be done
Unfortunately nothing happened. Futher code does not execute
-
@Creatorczyk Again: you don't start your thread anywhere, you just call a function named run() in your Camera object - nothing more.
-
@Christian-Ehrlicher calling "cameraThread.start();" will not start thread?
-
@Creatorczyk It will, but then you call a blocking function in your main thread.
-
cameraThread.start();
is the right thing to do. Yes, this starts a new thread "within" the object cameraThread. This call to start() does not block. Check it it out by inserting a qDebug() output right after the call.
But then you call (unnecessarily) Camera::run(), which will block. Use signals to "trigger" your camera object. Again, I think you mix up the two ways to use QThread: Usually you EITHER use the "moveToTrhread-style" OR the "reimplement QThread::run-style", but not both at the same time. If you want your code in Camera::run() to be executed without signaling, you have to call start() on your (then QThread derived) Camera object. Som thing likecamera->start();
should do the job. cameraThread is then not required at all.
-
@Creatorczyk said in Camera class in QThread:
calling "cameraThread.start();" will not start thread?
Did you read https://doc.qt.io/qt-5/qthread.html#start ?
start() calls run() - you do not have to call run() by yourself and you should NOT! -
@stryga42 @Christian-Ehrlicher @jsulm Thanks, I fixed it!