Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Problem with widgets in minimal integration of opencv
Forum Updated to NodeBB v4.3 + New Features

Problem with widgets in minimal integration of opencv

Scheduled Pinned Locked Moved Unsolved General and Desktop
amm
7 Posts 4 Posters 362 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.
  • A Offline
    A Offline
    ADAG
    wrote on last edited by
    #1

    Hi, i'm a beginnner and i use visual studio 2022 and the project is a c++ from the qt template.
    Opencv is correctly linked and all dll are present.

    I managed to get the video feed of a webcam in a qt window but the rest of the widgets are behaving weirdly.
    They have no code for now.

    I have done no sizing or placing of stuff for now so my program start like this :
    Capture2.PNG

    The widget at the top respond to the mouse when i click or hover them.
    Those on the right do nothing.

    If i extend the window i get this :
    Capture3.PNG

    The green part are responsive but the red part do nothing.

    The widgets are just added in the designer, all the same way just drag and drop.

    I have no idea what to do.
    Before i can make some functions and add more stuff i need buttons that work.

    my main.cpp:

    #include "QtWidgetsApplication1.h"
    #include <QtWidgets/QApplication>
    #include <QtWidgets/QLabel>
    #include <opencv2/opencv.hpp>
    
    #include <iostream>
    
    using namespace std;
    
    using namespace cv;
    
    int main(int argc, char* argv[])
    {
        QApplication a(argc, argv);
        QtWidgetsApplication1 w;
        w.show();
    
        // Create a QLabel to display the webcam feed
        QLabel* webcamLabel = w.getWebcamLabel();
        
        // Use 'webcamLabel->show()' instead of 'webcamLabel.show()'
        webcamLabel->show();
    
        // Open the default camera (camera index 0)
        VideoCapture cap(0);
    
        if (!cap.isOpened()) {
            // Use 'webcamLabel->setText' instead of 'label.setText'
            webcamLabel->setText("Cannot open camera");
            webcamLabel->repaint();
            return -1;
        }
    
        Mat frame;
    
        while (true) {
            // Read a frame from the camera
            cap >> frame;
    
            cv::cvtColor(frame, frame, cv::COLOR_BGR2RGB);
    
            if (frame.empty()) {
                // Use 'webcamLabel->setText' instead of 'label.setText'
                webcamLabel->setText("End of video stream");
                webcamLabel->repaint();
                break;
            }
    
            // Convert the OpenCV Mat to a QImage
            QImage qImage(frame.data, frame.cols, frame.rows, frame.step, QImage::Format_RGB888);
    
            // Display the QImage in the QLabel
            // Use 'webcamLabel->setPixmap' instead of 'webcamLabel.setPixmap'
            webcamLabel->setPixmap(QPixmap::fromImage(qImage));
            webcamLabel->repaint();
            
            // Pause for a short duration to control the frame rate
            QCoreApplication::processEvents();
        }
    
        return a.exec();
    }
    
    

    My QtWidgetsApplication1.h :

    #pragma once
    
    #include <QtWidgets/QMainWindow>
    #include "ui_QtWidgetsApplication1.h"
    #include <QLabel>
    #include <opencv2/opencv.hpp>
    
    class QtWidgetsApplication1 : public QMainWindow
    {
        Q_OBJECT
    
    public:
        QtWidgetsApplication1(QWidget* parent = nullptr);
        ~QtWidgetsApplication1();
    
        QLabel* getWebcamLabel() const { return webcamLabel; }
    
    
    
    private:
        Ui::QtWidgetsApplication1Class ui;
        QLabel* webcamLabel;            // QLabel to display the webcam feed
        cv::VideoCapture cap;           // OpenCV VideoCapture for webcam
        QTimer* timer;                  // QTimer to update the feed
        cv::Mat frame;                  // OpenCV Mat for holding frames
    
    };
    
    

    My QtWidgetsApplication1.cpp :

    #include "QtWidgetsApplication1.h"
    #include <QTimer>
    #include <QVBoxLayout>
    #include <opencv2/opencv.hpp>
    
    using namespace std;
    
    QtWidgetsApplication1::QtWidgetsApplication1(QWidget* parent)
        : QMainWindow(parent)
    {
        ui.setupUi(this); // Load the UI from the .ui file, including the existing central widget
    
        // Access the existing central widget
        QWidget* existingCentralWidget = centralWidget();
    
        // Create a layout for the existing central widget (e.g., QVBoxLayout)
        QVBoxLayout* layout = new QVBoxLayout(existingCentralWidget);
    
        webcamLabel = new QLabel(existingCentralWidget); // Create a QLabel for the webcam feed
        webcamLabel->setObjectName("webcamLabel"); // Set object name for later reference in Qt Designer
    
        // Add the webcamLabel to the layout
        layout->addWidget(webcamLabel);
        
        
    }
    
    
    QtWidgetsApplication1::~QtWidgetsApplication1()
    {}
    

    Any help is appreciated, since there is no code yet it is layout or refresh related but i don't know what to do to solve this.

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

      Hi and welcome to devnet,

      You should rather use a QTimer to grab the images rather than using a blocking loop like you do. Calling processEvent like that is a last resort solution that should be avoided.

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

      A 1 Reply Last reply
      2
      • SGaistS SGaist

        Hi and welcome to devnet,

        You should rather use a QTimer to grab the images rather than using a blocking loop like you do. Calling processEvent like that is a last resort solution that should be avoided.

        A Offline
        A Offline
        ADAG
        wrote on last edited by
        #3

        @SGaist Thank you for the advice

        Cleaned up main :

        #include "QtWidgetsApplication1.h"
        #include <QtWidgets/QApplication>
        #include <QtWidgets/QLabel>
        #include <opencv2/opencv.hpp>
        
        #include <iostream>
        
        using namespace std;
        
        using namespace cv;
        
        int main(int argc, char* argv[])
        {
            QApplication a(argc, argv);
            QtWidgetsApplication1 w;
            w.show();
        
            QLabel* webcamLabel = w.getWebcamLabel();
        
            webcamLabel->show();
        
            return a.exec();
        }
        
        

        Timer added in QtWidgetsApplication1.cpp :

        #include "QtWidgetsApplication1.h"
        #include <QTimer>
        #include <QVBoxLayout>
        #include <opencv2/opencv.hpp>
        
        using namespace std;
        
        QtWidgetsApplication1::QtWidgetsApplication1(QWidget* parent)
            : QMainWindow(parent)
        {
            ui.setupUi(this); // Load the UI from the .ui file, including the existing central widget
        
            // Access the existing central widget
            QWidget* existingCentralWidget = centralWidget();
        
            // Create a layout for the existing central widget (e.g., QVBoxLayout)
            QVBoxLayout* layout = new QVBoxLayout(existingCentralWidget);
        
            webcamLabel = new QLabel(existingCentralWidget); // Create a QLabel for the webcam feed
            webcamLabel->setObjectName("webcamLabel"); // Set object name for later reference in Qt Designer
        
            // Add the webcamLabel to the layout
            layout->addWidget(webcamLabel);
        
            // Open the default camera (camera index 0)
            cap.open(0, cv::VideoCaptureAPIs::CAP_DSHOW);
            if (!cap.isOpened()) {
                webcamLabel->setText("Cannot open camera");
                return;
            }
            cout << cap.get(cv::VideoCaptureProperties::CAP_PROP_FORMAT);
        
            // Create a QTimer to update the frame
            timer = new QTimer(this);
            connect(timer, SIGNAL(timeout()), this, SLOT(updateFrame()));
        
            timer->start(30);  // Adjust the interval as needed for your desired frame rate
        }
        
        QtWidgetsApplication1::~QtWidgetsApplication1()
        {}
        
        void QtWidgetsApplication1::updateFrame()
        {
            // Read a frame from the camera
            cap >> frame;
        
            // Convert the OpenCV Mat to a QImage (correcting color format from BGR to RGB)
            cv::Mat rgbFrame;
            cv::cvtColor(frame, rgbFrame, cv::COLOR_BGR2RGB);
            QImage qImage(rgbFrame.data, rgbFrame.cols, rgbFrame.rows, rgbFrame.step, QImage::Format_RGB888);
        
            // Display the QImage in the QLabel
            webcamLabel->setPixmap(QPixmap::fromImage(qImage));
        
            // Update the QLabel
            webcamLabel->update();
        }
        

        Still same behavior.

        SGaistS 1 Reply Last reply
        0
        • A ADAG

          @SGaist Thank you for the advice

          Cleaned up main :

          #include "QtWidgetsApplication1.h"
          #include <QtWidgets/QApplication>
          #include <QtWidgets/QLabel>
          #include <opencv2/opencv.hpp>
          
          #include <iostream>
          
          using namespace std;
          
          using namespace cv;
          
          int main(int argc, char* argv[])
          {
              QApplication a(argc, argv);
              QtWidgetsApplication1 w;
              w.show();
          
              QLabel* webcamLabel = w.getWebcamLabel();
          
              webcamLabel->show();
          
              return a.exec();
          }
          
          

          Timer added in QtWidgetsApplication1.cpp :

          #include "QtWidgetsApplication1.h"
          #include <QTimer>
          #include <QVBoxLayout>
          #include <opencv2/opencv.hpp>
          
          using namespace std;
          
          QtWidgetsApplication1::QtWidgetsApplication1(QWidget* parent)
              : QMainWindow(parent)
          {
              ui.setupUi(this); // Load the UI from the .ui file, including the existing central widget
          
              // Access the existing central widget
              QWidget* existingCentralWidget = centralWidget();
          
              // Create a layout for the existing central widget (e.g., QVBoxLayout)
              QVBoxLayout* layout = new QVBoxLayout(existingCentralWidget);
          
              webcamLabel = new QLabel(existingCentralWidget); // Create a QLabel for the webcam feed
              webcamLabel->setObjectName("webcamLabel"); // Set object name for later reference in Qt Designer
          
              // Add the webcamLabel to the layout
              layout->addWidget(webcamLabel);
          
              // Open the default camera (camera index 0)
              cap.open(0, cv::VideoCaptureAPIs::CAP_DSHOW);
              if (!cap.isOpened()) {
                  webcamLabel->setText("Cannot open camera");
                  return;
              }
              cout << cap.get(cv::VideoCaptureProperties::CAP_PROP_FORMAT);
          
              // Create a QTimer to update the frame
              timer = new QTimer(this);
              connect(timer, SIGNAL(timeout()), this, SLOT(updateFrame()));
          
              timer->start(30);  // Adjust the interval as needed for your desired frame rate
          }
          
          QtWidgetsApplication1::~QtWidgetsApplication1()
          {}
          
          void QtWidgetsApplication1::updateFrame()
          {
              // Read a frame from the camera
              cap >> frame;
          
              // Convert the OpenCV Mat to a QImage (correcting color format from BGR to RGB)
              cv::Mat rgbFrame;
              cv::cvtColor(frame, rgbFrame, cv::COLOR_BGR2RGB);
              QImage qImage(rgbFrame.data, rgbFrame.cols, rgbFrame.rows, rgbFrame.step, QImage::Format_RGB888);
          
              // Display the QImage in the QLabel
              webcamLabel->setPixmap(QPixmap::fromImage(qImage));
          
              // Update the QLabel
              webcamLabel->update();
          }
          

          Still same behavior.

          SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Did you benchmark your slot ?
          Why are you calling show on webcamLabel ? It should be shown automatically since it's part of QtWidgetsApplication1.
          By the way, there's no need to call update since you are changing the pixmap every time.

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

          A 1 Reply Last reply
          1
          • SGaistS SGaist

            Did you benchmark your slot ?
            Why are you calling show on webcamLabel ? It should be shown automatically since it's part of QtWidgetsApplication1.
            By the way, there's no need to call update since you are changing the pixmap every time.

            A Offline
            A Offline
            ADAG
            wrote on last edited by
            #5

            @SGaist
            I'm not sure how to use slots and i don't know what benchmark mean in this context.
            Indeed, webcamLabel.show and webcamLabel->update(); where unneeded, blame me who tried to use chatgpt to help.

            I found that removing completly all opencv code made the buttons work normally again.
            Since i don't know the inner workings of Qt, i don't know exactly how the opencv addition on the central widget mess with the buttons events and/or display.

            I'm working on a solution where the camera code is in a separate thread and right from the start the buttons all worked normally.

            jsulmJ 1 Reply Last reply
            0
            • A ADAG

              @SGaist
              I'm not sure how to use slots and i don't know what benchmark mean in this context.
              Indeed, webcamLabel.show and webcamLabel->update(); where unneeded, blame me who tried to use chatgpt to help.

              I found that removing completly all opencv code made the buttons work normally again.
              Since i don't know the inner workings of Qt, i don't know exactly how the opencv addition on the central widget mess with the buttons events and/or display.

              I'm working on a solution where the camera code is in a separate thread and right from the start the buttons all worked normally.

              jsulmJ Offline
              jsulmJ Offline
              jsulm
              Lifetime Qt Champion
              wrote on last edited by
              #6

              @ADAG said in Problem with widgets in minimal integration of opencv:

              I'm not sure how to use slots

              You're already using one:

              connect(timer, SIGNAL(timeout()), this, SLOT(updateFrame()));
              

              You should switch to newer Qt5 connect syntax, but this is another topic.

              I guess what @SGaist suggested is that you benchmark your updateFrame() slot to see where it spends most time.

              https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              2
              • A ADAG

                Hi, i'm a beginnner and i use visual studio 2022 and the project is a c++ from the qt template.
                Opencv is correctly linked and all dll are present.

                I managed to get the video feed of a webcam in a qt window but the rest of the widgets are behaving weirdly.
                They have no code for now.

                I have done no sizing or placing of stuff for now so my program start like this :
                Capture2.PNG

                The widget at the top respond to the mouse when i click or hover them.
                Those on the right do nothing.

                If i extend the window i get this :
                Capture3.PNG

                The green part are responsive but the red part do nothing.

                The widgets are just added in the designer, all the same way just drag and drop.

                I have no idea what to do.
                Before i can make some functions and add more stuff i need buttons that work.

                my main.cpp:

                #include "QtWidgetsApplication1.h"
                #include <QtWidgets/QApplication>
                #include <QtWidgets/QLabel>
                #include <opencv2/opencv.hpp>
                
                #include <iostream>
                
                using namespace std;
                
                using namespace cv;
                
                int main(int argc, char* argv[])
                {
                    QApplication a(argc, argv);
                    QtWidgetsApplication1 w;
                    w.show();
                
                    // Create a QLabel to display the webcam feed
                    QLabel* webcamLabel = w.getWebcamLabel();
                    
                    // Use 'webcamLabel->show()' instead of 'webcamLabel.show()'
                    webcamLabel->show();
                
                    // Open the default camera (camera index 0)
                    VideoCapture cap(0);
                
                    if (!cap.isOpened()) {
                        // Use 'webcamLabel->setText' instead of 'label.setText'
                        webcamLabel->setText("Cannot open camera");
                        webcamLabel->repaint();
                        return -1;
                    }
                
                    Mat frame;
                
                    while (true) {
                        // Read a frame from the camera
                        cap >> frame;
                
                        cv::cvtColor(frame, frame, cv::COLOR_BGR2RGB);
                
                        if (frame.empty()) {
                            // Use 'webcamLabel->setText' instead of 'label.setText'
                            webcamLabel->setText("End of video stream");
                            webcamLabel->repaint();
                            break;
                        }
                
                        // Convert the OpenCV Mat to a QImage
                        QImage qImage(frame.data, frame.cols, frame.rows, frame.step, QImage::Format_RGB888);
                
                        // Display the QImage in the QLabel
                        // Use 'webcamLabel->setPixmap' instead of 'webcamLabel.setPixmap'
                        webcamLabel->setPixmap(QPixmap::fromImage(qImage));
                        webcamLabel->repaint();
                        
                        // Pause for a short duration to control the frame rate
                        QCoreApplication::processEvents();
                    }
                
                    return a.exec();
                }
                
                

                My QtWidgetsApplication1.h :

                #pragma once
                
                #include <QtWidgets/QMainWindow>
                #include "ui_QtWidgetsApplication1.h"
                #include <QLabel>
                #include <opencv2/opencv.hpp>
                
                class QtWidgetsApplication1 : public QMainWindow
                {
                    Q_OBJECT
                
                public:
                    QtWidgetsApplication1(QWidget* parent = nullptr);
                    ~QtWidgetsApplication1();
                
                    QLabel* getWebcamLabel() const { return webcamLabel; }
                
                
                
                private:
                    Ui::QtWidgetsApplication1Class ui;
                    QLabel* webcamLabel;            // QLabel to display the webcam feed
                    cv::VideoCapture cap;           // OpenCV VideoCapture for webcam
                    QTimer* timer;                  // QTimer to update the feed
                    cv::Mat frame;                  // OpenCV Mat for holding frames
                
                };
                
                

                My QtWidgetsApplication1.cpp :

                #include "QtWidgetsApplication1.h"
                #include <QTimer>
                #include <QVBoxLayout>
                #include <opencv2/opencv.hpp>
                
                using namespace std;
                
                QtWidgetsApplication1::QtWidgetsApplication1(QWidget* parent)
                    : QMainWindow(parent)
                {
                    ui.setupUi(this); // Load the UI from the .ui file, including the existing central widget
                
                    // Access the existing central widget
                    QWidget* existingCentralWidget = centralWidget();
                
                    // Create a layout for the existing central widget (e.g., QVBoxLayout)
                    QVBoxLayout* layout = new QVBoxLayout(existingCentralWidget);
                
                    webcamLabel = new QLabel(existingCentralWidget); // Create a QLabel for the webcam feed
                    webcamLabel->setObjectName("webcamLabel"); // Set object name for later reference in Qt Designer
                
                    // Add the webcamLabel to the layout
                    layout->addWidget(webcamLabel);
                    
                    
                }
                
                
                QtWidgetsApplication1::~QtWidgetsApplication1()
                {}
                

                Any help is appreciated, since there is no code yet it is layout or refresh related but i don't know what to do to solve this.

                B Offline
                B Offline
                Bonnie
                wrote on last edited by Bonnie
                #7

                Oh, dear, the problem has nothing to do with opencv or video capture.
                If you add a frame to your QLabel like

                webcamLabel->setFrameShape(QFrame::Box);
                

                You will see that's your QLabel above other widgets, so blocking their mouse events.

                About the "responsive" top part, that's because QVBoxLayout has default 9px margins.
                If you add

                layout->setContentsMargins(0, 0, 0, 0);
                

                Then they'll be not responsive at all.

                So the problem can be easily solved after you learn how to properly use layouts to arrange the widgets and not let anyone block others.
                I think you are just copying the code from somewhere else, right? The orignal example probably doesn't use ui file and only has an empty window.
                In your case, I would suggest that don't create the layout and the label in the cpp file, but in the ui file with all the other widgets.

                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 Extensions
                • Unsolved