2015-10-04 93 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