2015-10-04 84 views
1

我创建Qt中用于学习目的的简单的应用程序。我想显示网络摄像头捕获的图像以显示在我的用户界面(ui)的图形视图中。信号和槽线程

功能:当按下开始按钮,摄像头帧开始越来越显示图形视图。当按下暂停按钮时,网络摄像头流被暂停。最后,如果按下退出按钮然后,整个应用程序被终止。

我的方法:我想在按下启动按钮时启动Qt线程,并且此线程将持续捕获网络摄像头帧。在捕获每个摄像头帧后,该线程将发出一个信号并将指针传递给捕获图像的数据,其高度和宽度。该信号将连接到MainWindow类的插槽(即setGraphicsView())。 MainWindow类的插槽会将捕获的摄像头图像分配给UI的GraphicsView。

我的代码:

的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; 
} 

问题:我收到以下运行时错误:

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') 
+2

从connect()声明中删除像ptrFrame,ih,iw这样的参数名称 –

+0

@FrankOsterfeld:我试过了,但它没有帮助 – user2756695

回答

0

这段代码有这么多问题!

  1. 你并不需要在这里线程。 QTimer是更好和更安全的解决方案(你会犯的错误更少)
  2. 子分类QThreadis bad approach when handling threads(我不会解释为什么,因为你不应该使用它们)。
  3. 你的信号是被严重定义插槽,什么会导致内存管理的问题。从cv::MatQPixmap
  4. 转换方法是a bit more complicated
  5. 您要显示在QGraphicsView是完全错误的方式。你应该read documentation how to use this part of Qt

底线有一个很长的路要让你的东西正常工作。国际海事组织,你应该采取一些简单的事情来开始几步。现在你在很多领域缺乏技能(至少3个),这对你学习任何东西都会非常痛苦。当时在一个新领域提高技能。

+0

感谢您的建议。事实上,我是一名初学者,需要学习很多东西。根据您的建议,我使用QTimer制作了这种应用程序。有时候,应用程序的响应,但其他一些时候没有。顺便说一句,我得到这个答案,也说为此目的使用QThread'http:// stackoverflow.com/a/11606773/2756695'。你能否在我原来的帖子中指出这些问题,尽管我的风格很糟糕,所以我可以改进和学习更多。 – user2756695