I am creating a simple application in Qt for learning purpose. I want to display the images captured by the webcam to be displayed in a Graphicsview of my User Interface (ui).
Functionality: When the Start button is pressed, the webcam frames start getting displayed in the Graphics View. When the Paused button is pressed, the webcam streaming gets paused. And finally, if the Quit button is pressed then, the whole application gets terminated.
My Approach: I want to start a Qt thread when the start button is pressed and this thread will continuously capture the webcam frames. After capturing each webcam frame, this thread will emit a signal and pass the pointer to the data of captured image, its height and its width. This signal will be connected to a slot (i.e. setGraphicsView()
) of MainWindow
class. The slot of MainWindow
class will assign the captured webcam image to the GraphicsView of ui.
My Code:
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow *w = new MainWindow;
w->show();
return a.exec();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
//Threading
#include "thread.h"
//OpenCV
#include <opencv2/core.hpp>
#include<opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include "opencv2/opencv.hpp"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_StartButton_clicked();
void on_PauseButton_clicked();
void on_QuitButton_clicked();
void setGraphicsView(unsigned char* ptrWebcamImg, int iw, int ih);
private:
Ui::MainWindow *ui;
Thread guiThread;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QGraphicsPixmapItem>
using namespace cv;
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
QObject::connect(ui->StartButton, SIGNAL(clicked()), &guiThread, SLOT(start()), Qt::QueuedConnection);
//When the thread emits a signal saying it has got a new webcam frame, reflect that change in the graphicsview of ui.
QObject::connect(&guiThread,SIGNAL(signalGotNewFrame(const unsigned char* ptrWebcamImage, int iw, int ih)),this,SLOT(setGraphicsView(const unsigned char* ptrWebcamImage, int iw, int ih)), Qt::QueuedConnection);
QObject::connect(ui->PauseButton, SIGNAL(clicked()), &guiThread, SLOT(stopRunning()), Qt::QueuedConnection);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::setGraphicsView(unsigned char *ptrWebcamImg, int iw, int ih)
{
Mat frame(ih, iw, CV_8UC3, Scalar(0,0,255));
//Conver the Mat frame into QImage and assign it to the GraphicsView of ui.
QImage image( frame.data, frame.cols, frame.rows, frame.step, QImage::Format_RGB888 );
QGraphicsScene* scene = new QGraphicsScene();
QGraphicsPixmapItem* item = new QGraphicsPixmapItem(QPixmap::fromImage(image));
scene->addItem(item);
ui->graphicsView->setScene(scene);
}
void MainWindow::on_StartButton_clicked()
{
}
void MainWindow::on_PauseButton_clicked()
{
//guiThread.stopRunning();
}
void MainWindow::on_QuitButton_clicked()
{
connect(ui->QuitButton,SIGNAL(released()), qApp, SLOT(quit()));
}
thread.h
#ifndef THREAD_H
#define THREAD_H
#include <QThread>
class Thread : public QThread
{
Q_OBJECT
public slots:
void stopRunning();
//virtual void run();
protected:
virtual void run();
private:
bool isWebcamNeeded;
signals:
void signalGotNewFrame(unsigned char* ptrFrame, int iw, int ih);
};
#endif // THREAD_H
thread.cpp
#include "thread.h"
//Qt and
#include <QGraphicsPixmapItem>
#include <iostream>
//OpenCV related
#include <opencv2/core.hpp>
#include<opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
using namespace cv;
void Thread::run()
{
std::cout<<"\nIn the thread"<<std::endl;
isWebcamNeeded = true;
cv::VideoCapture cap(0);
Mat frame;
unsigned char *ptrFrame;
while(isWebcamNeeded == true) //"this->isWebcamNeeded" will become false when PauseButton will be clicked
{
cap >> frame;
ptrFrame = frame.data;
emit signalGotNewFrame(ptrFrame, frame.cols, frame.rows);
}
}
void Thread::stopRunning()
{
isWebcamNeeded = false;
}
Problem: I am getting the following runtime errors:
QObject::connect: No such signal Thread::signalGotNewFrame(const unsigned char* ptrWebcamImage, int iw, int ih) in ../MyCamApp/mainwindow.cpp:12
QObject::connect: (receiver name: 'MainWindow')