Results 1 to 2 of 2

Thread: QT label update. Different threads.

  1. #1
    Join Date
    Mar 2017
    Posts
    1
    Qt products
    Qt5 PyQt3 PyQt4
    Platforms
    Unix/X11 Windows Android

    Default QT label update. Different threads.

    I got stuck with GUI update. I have 2 classes : ControlWidget in main thread and CameraController in the separate thread.
    Qt Code:
    1. int main(int argc, char **argv)
    2. {
    3. QApplication app(argc, argv);
    4. CameraController *cameraController = new CameraController;;
    5. ControlWidget *main_window = new ControlWidget;
    6. Thread getImageThread;
    7. cameraController->moveToThread(&getImageThread);
    8. getImageThread.start();
    9. QTimer get_images_timer;
    10. QObject::connect(&get_images_timer, SIGNAL(timeout()), cameraController, SLOT(onTimerOut()), Qt::QueuedConnection);
    11. QObject::connect(cameraController, SIGNAL(sendLabel(QImage)), main_window, SLOT(getImage(QImage)), Qt::QueuedConnection);
    12. QObject::connect(&get_images_timer, SIGNAL(timeout()), main_window, SLOT(update()), Qt::QueuedConnection);
    13. get_images_timer.start(2000);
    14. app.exec();
    15. return 0;
    16. }
    To copy to clipboard, switch view to plain text mode 


    so every 2 seconds i want to get images from camera thread and send them to main thread (that actionally happens, so I have QImage at the main_window object). Then I want to put this QImage to the cam1 and cam2 QLabels. And here I am stuck:

    First: when I use setPixmap() method the QLabel.width() and QLabel.height() are different then image.width() and image.height() or pixmap.width() and pixmap.height().

    Second: I can not visualize the QLabel. If I do this->ImageLayout->addWidget(cam1) nothing really happens. this->update doesn't help either.

    Shall I have an extra worker for GUI Update?

    What am I doing wrong?

    Source code for more information :

    CameraController.h


    Qt Code:
    1. class CameraController : public QObject
    2. {
    3. Q_OBJECT
    4.  
    5. private:
    6. CoreApi::InstanceHandle g_hApi;
    7. CoreApi::DeviceCollectionHandle hDeviceCollection;
    8. CoreApi::DeviceHandle hDevice;
    9. CoreApi::CameraPortHandle first_cam;
    10. Common::FrameHandle frame;
    11.  
    12. QPixmap pixmap;
    13. QImage image;
    14.  
    15. public:
    16. CameraController();
    17. ~CameraController();
    18. QLabel outLabel;
    19.  
    20. public slots:
    21. void onTimerOut();
    22.  
    23. signals:
    24. QImage sendLabel(QImage image);
    25. };
    To copy to clipboard, switch view to plain text mode 

    CameraController.cpp
    Qt Code:
    1. CameraController::CameraController()
    2. {
    3. try
    4. {
    5. this->g_hApi = CoreApi::Instance::initialize();
    6. this->hDeviceCollection = this->g_hApi->deviceCollection();
    7. this->hDevice = hDeviceCollection->device(0);
    8. this->first_cam = hDevice->cameraPort(0);
    9. first_cam->autoConfigure();
    10. first_cam->liveStart();
    11. }
    12. catch (GeneralException& e)
    13. {
    14. std::cout << e.what() << std::endl;
    15. }
    16. }
    17.  
    18. CameraController::~CameraController()
    19. {
    20. }
    21.  
    22. void CameraController::onTimerOut()
    23. {
    24. if (this->first_cam->liveFrameReady())
    25. {
    26. this->frame = first_cam->liveFrame();
    27. this->image = QImage((uchar*)this->frame->buffer()->data(), this->frame->dataType()->width(), this->frame->dataType()->height(), QImage::Format::Format_RGB888);
    28. this->image = this->image.scaled(QSize(this->image.width()/10, this->image.height()/10));
    29. std::cout << "width = "<<this->image.width() << "height = " << this->image.height() << std::endl;
    30. emit sendLabel(this->image.copy());
    31. }
    32. }
    To copy to clipboard, switch view to plain text mode 

    ControlWidget.h

    Qt Code:
    1. class ControlWidget :public QDialog
    2. {
    3. Q_OBJECT
    4. private:
    5. QGLCanvas *osCanvas;
    6. QGridLayout *mainLayout;
    7. QGridLayout *buttonLayout;
    8.  
    9. QVBoxLayout *settingsLayout;
    10. QHBoxLayout *controlLayout;
    11. QListWidget *cameraListWidget, *devicesListWidget;
    12. QLabel *cameraListLabel, *devicesListLabel, *cameraSettingsLabel, *fpsLabel, *shutterLabel;
    13. QHBoxLayout *fpsLayout, *shutterLayout;
    14. QLineEdit *fpsEdit, *shutterEdit;
    15. QPushButton *saveButton, *saveSettingButton, *applySettingsButton, *chooseFolderButton;
    16. QTimer* m_timer;
    17. public:
    18. ControlWidget(QWidget *parent = 0);
    19. ~ControlWidget();
    20. QVBoxLayout *imageLayout = new QVBoxLayout;
    21. QLabel *cam1 = new QLabel;
    22. QLabel *cam2 = new QLabel;
    23. QImage *camera_1, *camera_2;
    24. void createWidgets();
    25. public slots:
    26. void getImage(QImage new_frame);
    27. void displayImages();
    28. signals:
    29. void images_loaded();
    30. private slots:
    31. void onTimeout()
    32. {
    33. qDebug() << "Worker::onTimeout get called from controlWidget timer and ?: " << QThread::currentThreadId();
    34. };
    35. };
    To copy to clipboard, switch view to plain text mode 

    ControlWidget.cpp

    Qt Code:
    1. ControlWidget::ControlWidget(QWidget *parent)
    2. {
    3. //this->createWidgets();
    4. this->m_timer = new QTimer;
    5. connect(this->m_timer, SIGNAL(timeout()),this, SLOT(update()));
    6. m_timer->start(1000);
    7. }
    8.  
    9. ControlWidget::~ControlWidget()
    10. {
    11. delete this->mainLayout;
    12. }
    13.  
    14. void ControlWidget::createWidgets()
    15. {
    16. this->imageLayout->addWidget(cam1);
    17. this->imageLayout->addWidget(cam2);
    18. this->setLayout(this->imageLayout);
    19. this->show();
    20. }
    21.  
    22. void ControlWidget::displayImages()
    23. {
    24. QLabel tmp_label ;
    25.  
    26. std::cout << "********************************************************************************" << std::endl;
    27. std::cout <<" camera height = " <<this->camera_1->height() << " camera width = " << this->camera_1->width() << std::endl;
    28. std::cout << "********************************************************************************" << std::endl;
    29. QPixmap tmp_pixmap = QPixmap::fromImage(this->camera_1->copy());
    30. std::cout << "PIXMAP WIDTH = " << tmp_pixmap.width() << "Pixmap Height = " << tmp_pixmap.height() <<std::endl;
    31. tmp_label.setGeometry(200, 200, tmp_pixmap.width(), tmp_pixmap.height());
    32. std::cout << "LABELWIDTH = " << tmp_label.width() << "LabelHeight = " << tmp_label.height() << std::endl;
    33. tmp_label.show();
    34. this->cam1 = &tmp_label;
    35. this->cam2 = &tmp_label;
    36. std::cout << "CAM1 Width = " <<this->cam1->width() << std::endl;
    37. this->createWidgets();
    38. }
    39. void ControlWidget::getImage(QImage img)
    40. {
    41. std::cout << "********************************************************************************" << std::endl;
    42. std::cout << " img height = " << img.height() << " img width = " << img.width() << std::endl;
    43. std::cout << "********************************************************************************" << std::endl;
    44. this->camera_1 = &QImage(img);
    45. this->camera_2 = &QImage(img);
    46. this->displayImages();
    47. }
    To copy to clipboard, switch view to plain text mode 

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,229
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: QT label update. Different threads.

    I don't see any call to main_window->show() in your main(). That should happen just before app.exec().

    Edit: Your code is extremely confused. I see now that you call show() in createWidgets(), but this method is commented out.

    And this code:

    Qt Code:
    1. this->camera_1 = &QImage(img);
    2. this->camera_2 = &QImage(img);
    To copy to clipboard, switch view to plain text mode 

    is totally wrong. You are creating two QImage instances -on the stack (QImage(img))- and these instance are destroyed immediately when your method exits. So camera_1 and camera_2 are assigned pointer values which become invalid and dangling as soon as the method is done.

    To do this correctly, you could change camera_1 and camera_2 from being QImage * to simply QImage and just assign the incoming image to them:

    Qt Code:
    1. // .h:
    2.  
    3. QImage camera_1;
    4. QImage camera_2;
    5.  
    6. // .cpp:
    7.  
    8. this->camera_1 = img;
    9. this->camera_2 = img;
    To copy to clipboard, switch view to plain text mode 

    The same error occurs here:

    Qt Code:
    1. this->cam1 = &tmp_label;
    2. this->cam2 = &tmp_label;
    To copy to clipboard, switch view to plain text mode 

    You are assigning the address of a temporary QLabel variable which gets destroyed as soon as the method exits, so cam1 and cam2 end up pointing to a non-existent QLabel instance.

    You need to go back to your C++ textbook and read about variables and scoping.
    Last edited by d_stranz; 22nd March 2017 at 04:17.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

Similar Threads

  1. Replies: 4
    Last Post: 9th September 2015, 19:06
  2. Threads, Timer and Update a Field
    By lima_will in forum Newbie
    Replies: 2
    Last Post: 2nd October 2013, 09:05
  3. Update GUI from another object with 2 threads.
    By jiapei100 in forum Qt Programming
    Replies: 8
    Last Post: 19th February 2013, 18:27
  4. unable to update label from another thread
    By dhanya.v in forum Qt Programming
    Replies: 1
    Last Post: 4th October 2012, 13:05
  5. How to update GUI promptly with data sent from threads
    By Eos Pengwern in forum Qt Programming
    Replies: 3
    Last Post: 7th October 2010, 12:33

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.