Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. 3rd Party Software
  4. [SOLVED] QT MainWindow freezes when closing OpenCV Webcam Window - new QT Window outside MainWindow
Qt 6.12 LTS is out! See what's new in the release blog

[SOLVED] QT MainWindow freezes when closing OpenCV Webcam Window - new QT Window outside MainWindow

Scheduled Pinned Locked Moved 3rd Party Software
30 Posts 2 Posters 30.4k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • ? Offline
    ? Offline
    A Former User
    wrote on last edited by
    #11

    I get my images from a run loop within this CLEyeCameraCapture class in a defined fps rate. I would like to parse the signal of this runloop to any QT Window eg. pseudo:

    @run(){
    while(runnig){

    iplimage = getImage(Camera);
    QImage = IPLtoQimage(iplimage);
    newwindow.show(QImage);
    }
    }@

    I am thinking now that the cleanest way to do that would be to create a newWindow in the mainWindow .cpp and then access this window in my QObject class (which inherits the run loop and camera access).

    But i lack of experience to find the right expressions.

    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #12

      Then I would recommend taking a look at the "MandelBrot example":http://qt-project.org/doc/qt-4.8/threads-mandelbrot.html

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • ? Offline
        ? Offline
        A Former User
        wrote on last edited by
        #13

        hey SGaist, thanks for the info but i already got the whole loop and my problem is just to connect the image created in the loop with the QDialog (parent) of the class.

        I took a look at this:

        http://www.sobbayi.com/blog/software-development/access-members-parent-class-qt-c/

        which kind of is what I'm searching. it works ok except i cannot see the image due to i made something wrong with the label.

        in my child class this compiles fine:

        @ while(_running)
        {
        CLEyeCameraGetFrame(_cam, pCapBuffer);

        // Resize Image to fit screen size
        cvResize(pCapImage,resizedpCapImage,CV_INTER_NN);
        cvShowImage(_windowName, resizedpCapImage);

        *qimg = IplImage2QImage(resizedpCapImage);

        parentqlabel->setPixmap(QPixmap::fromImage(*qimg));
        parentqlabel->show();@

        but does not show the image

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #14

          The technique described in this article is exactly what is discouraged to do in general. The basic idea with Qt is to emit a signal from the child class that the parent class connects to. So the child class doesn't need to know anything about the parent (keeps the code clean). Or if you don't want a signal (in a dialog case) you use getters once your done with the dialog.

          Back to your problem, you are using an infinite loop in the main thread so this will block everything, hence the mandlebrot example.

          Also why make qimg a pointer ? You don't need that, just make in a regular QImage. You will avoid memory management problem.

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          0
          • ? Offline
            ? Offline
            A Former User
            wrote on last edited by
            #15

            I get that its discouraged and i get that this is not pro's programming here but I need to get it to work asap so I'm willing to take hate :)

            In my CameraCapture class i declared the variable like the following, if you can point me out the correct way it would be nice. As I mentioned I am a C++ starter.

            @ QImage *qimg = new QImage();

            //Create Buffer for pCap
            PBYTE pCapBuffer = NULL;

            // Create camera instance
            _cam = CLEyeCreateCamera(_cameraGUID, _mode, _resolution, _fps);
            if(_cam == NULL)
            ...
            ...
            ...

            // Start capturing
            CLEyeCameraStart(_cam);
            cvGetImageRawData(pCapImage, &pCapBuffer);
            // image capturing loop
            while(_running)
            {
            CLEyeCameraGetFrame(_cam, pCapBuffer);

            // Resize Image to fit screen size
            cvResize(pCapImage,resizedpCapImage,CV_INTER_NN);
            cvShowImage(_windowName, resizedpCapImage);

            *qimg = IplImage2QImage(resizedpCapImage);@

            Also, as you complained the child process and parent process might be switched here, so I guess I could make the CaptureClass parent of the CameraWindow Class which would leed to:

            MainWindow (QMainWindow) --> creates CaptureObject (QObject)
            CaptureObject (QObject) -> creates and is parent of CameraWindow (QDialog)

            This is the only solution I can think of as I see that I have thread problems because I can not create communication between CaptureObject and Camera Window now.

            @ parentqlabel->setTextFormat(Qt::RichText);
            parentqlabel->setText("textest");@

            creates

            ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 48cb8f8. Receiver '' (of type 'QLabel') was created in thread 23c0790", file kernel\qcoreapplication.cpp, line 535
            ASSERT failure in QCoreApplication::sendEvent: "Cannot send events to objects owned by a different thread. Current thread 23c0790. Receiver '' (of type 'QTextDocument') was created in thread 48cb8f8", file kernel\qcoreapplication.cpp, line 535

            This is because the CameraCaptureSDK provided code creates a thread :

            @_hThread = CreateThread(NULL, 0, &CLEyeCameraCapture::CaptureThread, this, 0, 0);@

            ...
            @
            DWORD WINAPI CLEyeCameraCapture::CaptureThread(LPVOID instance)
            {
            // seed the rng with current tick count and thread id
            srand(GetTickCount() + GetCurrentThreadId());
            // forward thread to Capture function
            CLEyeCameraCapture *pThis = (CLEyeCameraCapture *)instance;
            pThis->Run();
            return 0;@

            1 Reply Last reply
            0
            • ? Offline
              ? Offline
              A Former User
              wrote on last edited by
              #16

              ok so i put my new window as part of the cameracapture class and it opens and closes...wonderfull, but MainWindow GUI freezes again when hitting the close button on it to close my window.

              here i am..back at the beginning

              1 Reply Last reply
              0
              • SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #17

                That's exactly why I suggested the mandelbrot example, you have there an example of how to implement an forever loop and interact with your application.

                You can't update GUI elements from outside the main thread.

                Could you post a link to the sdk ?

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 Reply Last reply
                0
                • ? Offline
                  ? Offline
                  A Former User
                  wrote on last edited by
                  #18

                  Here are the links:

                  http://codelaboratories.com/research/view/cl-eye-platform-cpp-sample

                  http://codelaboratories.com/get/cl-eye-sdk/

                  the window now closes (typing mistake) correctly. (yeij)

                  so now if i do this:

                  @CameraWindow::CameraWindow(QWidget *parent)
                  : QDialog(parent)
                  {
                  ui.setupUi(this);
                  imageLabel = new QLabel(this);
                  imageLabel->setTextFormat(Qt::RichText);
                  imageLabel->setText("textest");
                  }

                  CameraWindow::~CameraWindow()
                  {

                  }
                  @

                  and create a window within my capture class this opens correctly and text is displayed. but if i try to make this a function

                  @CameraWindow::CameraWindow(QWidget *parent)
                  : QDialog(parent)
                  {
                  ui.setupUi(this);
                  imageLabel = new QLabel(this);
                  }

                  CameraWindow::~CameraWindow()
                  {

                  }

                  void CameraWindow::dispText(){
                  imageLabel->setTextFormat(Qt::RichText);
                  imageLabel->setText("textest");
                  }@

                  and call camerawindow->dispText() from my capture class i get a "Cannot create children for a parent that is in a different thread" which is akward because obviously imageLabel should be an instance within my CameraWindow not anything else. as CameraWindow is created within this class i really wonder what's going on :)

                  To your remark: Even if i create a dialog within another thread (obviously another thread because it says so) the GUI Element QLabel i create within this new dialog can only be updated in my MainWindow thread?

                  If I understand you pointing to the mandelbrot example the solution would be to exchange the orignal sdk thread:

                  @HANDLE _hThread@

                  @_hThread = CreateThread(NULL, 0, &CLEyeCameraCapture::CaptureThread, this, 0, 0);@

                  with another QT Thread creation...

                  @
                  RenderThread::RenderThread(QObject *parent)
                  : QThread(parent)

                  @

                  which is kind of what i do not feel capable of :)

                  1 Reply Last reply
                  0
                  • SGaistS Offline
                    SGaistS Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on last edited by
                    #19

                    Creating widgets outside the main thread is also forbidden.

                    Here is a rough idea on how to use a subclassed QThread to get the data from the camera and send them to your widget. (Just the run function actually but it's the most important)

                    @
                    void MyQThread::run()
                    int w, h;
                    IplImage *pCapImage;
                    PBYTE pCapBuffer = NULL;

                        // Create camera instance
                        _cam = CLEyeCreateCamera(_cameraGUID, _mode, _resolution, _fps);
                        if(_cam == NULL)        return;
                        // Get camera frame dimensions
                        CLEyeCameraGetFrameDimensions(_cam, w, h);
                    

                    // Depending on color mode chosen, create the appropriate OpenCV image
                    if(_mode == CLEYE_COLOR)
                    pCapImage = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 4);
                    else
                    pCapImage = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1);

                        // Set some camera parameters
                        CLEyeSetCameraParameter(_cam, CLEYE_GAIN, 20);
                        CLEyeSetCameraParameter(_cam, CLEYE_EXPOSURE, 511);
                        CLEyeSetCameraParameter(_cam, CLEYE_ZOOM, (int)(GetRandomNormalized()*100.0));
                        CLEyeSetCameraParameter(_cam, CLEYE_ROTATION, (int)(GetRandomNormalized()*300.0));
                    
                        // Start capturing
                        CLEyeCameraStart(_cam);
                        // image capturing loop
                        while(_running)
                        {
                            cvGetImageRawData(pCapImage, &pCapBuffer);
                            CLEyeCameraGetFrame(_cam, pCapBuffer);
                             emit capturedImage(IplImage2QImage(pCapImage));
                        }
                        // Stop camera capture
                        CLEyeCameraStop(_cam);
                        // Destroy camera object
                        CLEyeDestroyCamera(_cam);
                        _cam = NULL;
                    }
                    

                    @

                    Depending on the image format you could even directly capture to a QImage avoiding the conversion.

                    Hope it helps

                    Interested in AI ? www.idiap.ch
                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                    1 Reply Last reply
                    0
                    • ? Offline
                      ? Offline
                      A Former User
                      wrote on last edited by
                      #20

                      thank you so much for your answers and your advice.
                      i'll try to implement this with looking at the mandelbrot example and post updates here.

                      1 Reply Last reply
                      0
                      • ? Offline
                        ? Offline
                        A Former User
                        wrote on last edited by
                        #21

                        I followed the mandelbrot example and did alike with my class.

                        Now, I am not able to acces wait(), start(), isRunning() or any other static (protected?) function which seems either not to be declared or not found.

                        I included the following, something's missing ?
                        @
                        #include <QCoreApplication>
                        #include <QThread>
                        #include <QObject>
                        #include <QMutex>
                        #include <QWaitCondition>
                        @

                        ok...it seems that this is because i create a dialog window within the render thread that seems not to be able to parent correctly.

                        i guess the way would be to open the camerwindow dialog within the mainwindow class and connect the signal of the renderthread to the camerwindow ?

                        1 Reply Last reply
                        0
                        • SGaistS Offline
                          SGaistS Offline
                          SGaist
                          Lifetime Qt Champion
                          wrote on last edited by
                          #22

                          Did you subclass QThread and use the code in the run function ?

                          No widget stuff whatsoever in another thread than the GUI thread (they mean it)

                          That would be one way yes

                          Interested in AI ? www.idiap.ch
                          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                          1 Reply Last reply
                          0
                          • ? Offline
                            ? Offline
                            A Former User
                            wrote on last edited by
                            #23

                            Ok, seems that something is wrong with the connection:

                            @1>.\camerawindow.cpp(14) : error C2664: 'bool QObject::connect(const QObject *,const char *,const QObject *,const char *,Qt::ConnectionType)': Konvertierung des Parameters 1 von 'RenderThread **' in 'const QObject *' nicht möglich
                            1> Die Typen, auf die verwiesen wird, sind nicht verknüpft; die Konvertierung erfordert einen reinterpret_cast-Operator oder eine Typumwandlung im C- oder Funktionsformat.@

                            although i defined RenderThread as in the example..

                            @class RenderThread : public QThread
                            {
                            Q_OBJECT
                            @

                            1 Reply Last reply
                            0
                            • SGaistS Offline
                              SGaistS Offline
                              SGaist
                              Lifetime Qt Champion
                              wrote on last edited by
                              #24

                              it seems that you are giving the address of the pointer to your RenderThread.

                              Do you have something like that :

                              @RenderThread *renderThread = new RenderThread;
                              conncet(&renderThread, etc....)@

                              ?

                              Interested in AI ? www.idiap.ch
                              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                              1 Reply Last reply
                              0
                              • ? Offline
                                ? Offline
                                A Former User
                                wrote on last edited by
                                #25

                                thanx, i'm tryin hard to get this to work ;)
                                it's really chaos now..

                                1 Reply Last reply
                                0
                                • SGaistS Offline
                                  SGaistS Offline
                                  SGaist
                                  Lifetime Qt Champion
                                  wrote on last edited by
                                  #26

                                  The best is to go one step at a time, first get the data from the camera, then add the widget etc... Trying to make all at the same time is recipe for failure

                                  Interested in AI ? www.idiap.ch
                                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                                  1 Reply Last reply
                                  0
                                  • ? Offline
                                    ? Offline
                                    A Former User
                                    wrote on last edited by
                                    #27

                                    going with your version didn't work out so i went with this:

                                    camerawindow.cpp:

                                    @CameraWindow::CameraWindow(QWidget *parent)
                                    : QDialog(parent)
                                    {
                                    ui.setupUi(this);
                                    QLabel *imageLabel = new QLabel(this);

                                    qRegisterMetaType<QImage>("QImage");
                                    connect(&thread, SIGNAL(renderedImage(QImage)),
                                    this, SLOT(updatePixmap(QImage)));

                                    setWindowTitle(tr("multithread"));
                                    }

                                    ...

                                    int CameraWindow::startCaptureThread(){
                                    this->show();

                                    RenderThread *thread = new RenderThread(this, windowName, guid, CLEYE_COLOR_RAW, CLEYE_VGA, 50);

                                    thread->StartCapture("abc");
                                    }
                                    @

                                    which seems to work fine as looping the run() while loop correctly,

                                    but obviously the updatePixmap function is never called so the objects might be mislinked or created in wrong syntax... frustrating ;)

                                    1 Reply Last reply
                                    0
                                    • ? Offline
                                      ? Offline
                                      A Former User
                                      wrote on last edited by
                                      #28

                                      i tried with another connection:

                                      @ connect(&thread, SIGNAL(sendText(std::string)),
                                      this, SLOT(debugSomething(std::string)));@

                                      @void CameraWindow::debugSomething(std::string something){
                                      QString somethings(something.c_str());
                                      qDebug()<<somethings;
                                      }@

                                      renderthread.cpp:
                                      @while(_running)
                                      {
                                      emit sendText(text);
                                      }@

                                      and this as well seems not to emit anything or not correctly connect to the qdialog. why is this not working as it should ?

                                      1 Reply Last reply
                                      0
                                      • SGaistS Offline
                                        SGaistS Offline
                                        SGaist
                                        Lifetime Qt Champion
                                        wrote on last edited by
                                        #29

                                        You should replace all std::string with QString, that will avoid you some problems.
                                        Your while loop might be a bit short and might block the main thread.

                                        If your code is not top secret, could you share it i.e. via gitorious/github/other vcs service ? That might make things easier to look at

                                        Interested in AI ? www.idiap.ch
                                        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                                        1 Reply Last reply
                                        0
                                        • ? Offline
                                          ? Offline
                                          A Former User
                                          wrote on last edited by
                                          #30

                                          Hi SGaist,

                                          after getting a bit tired refitting the Mandelbrot Example to my needs I asked this question at StackOverflow. It turns out that there are some issues the way the example uses threads. I don't know if I could have saved my code but I was getting depressed so I recoded the way somebody pointed me out at StackOverflow and this worked instantly and also avoids image conversion as i can use the opencv namendWindow.

                                          @//create new thread
                                          QThread* thread = new QThread;

                                          //init camera with guid, raw color capture, vga format and 50fps
                                          cameraCapture = new CLEyeCameraCapture(winName, folder, userID, guid, CLEYE_COLOR_RAW, CLEYE_VGA, 50);
                                          cameraCapture->moveToThread(thread);

                                          connect(thread, SIGNAL(started()), cameraCapture, SLOT(StartCapture()));
                                          connect(cameraCapture, SIGNAL(finished()), thread, SLOT(quit()));
                                          connect(cameraCapture, SIGNAL(finished()), cameraCapture, SLOT(deleteLater()));
                                          connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
                                          connect(ui.pushButton_startLogging, SIGNAL ( clicked() ),this,SLOT( activateLogging() ) );
                                          connect(ui.pushButton_stopLogging, SIGNAL ( clicked() ),this,SLOT( deactivateLogging() ) );
                                          @

                                          I tried to follow this "example.":http://mayaposch.wordpress.com/2011/11/01/how-to-really-truly-use-qthreads-the-full-explanation/

                                          Here is the "Question on SO.":http://stackoverflow.com/questions/18594528/create-thread-in-qdialog-and-emit-signals-to-qdialog-in-qt

                                          Thank you for your help. Now i avoided the freezes. It might be of interest for people who using any conversion from IplImage to QImage: non of the conversions are fast enough for realtime (I did not measure wether the conversion or the displaying method is slowing down the process).

                                          Thank you anyway for your help. I guess it is wise for anybody who rebuilds this to use their original code and put it in a Worker which then gets moved to a QThread.

                                          1 Reply Last reply
                                          0

                                          • Login

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular
                                          • Users
                                          • Groups
                                          • Search
                                          • Get Qt
                                          • Unsolved