1. 程式人生 > >Qt+halcon 第一個程式 QObject類的定時器應用

Qt+halcon 第一個程式 QObject類的定時器應用

最近決定學習一下Qt了,主要有一下原因: 1、同MFC相比Qt應該是一個簡單易用的C++類庫了。特別是Qt5開始他把串列埠的通訊甚至Modbus的通訊都做成了類,這是給工控開發人員提供了極大的方便,又可以少造點輪子。 2、MFC及Qt的對比使用,也能增強對基礎的理解。 用halcon結合Qt做視覺第一個問題是環境的配置:
#includes
INCLUDEPATH += "$$(HALCONROOT)/include"
INCLUDEPATH += "$$(HALCONROOT)/include/halconcpp"

#libs
QMAKE_LIBDIR += "$$(HALCONROOT)/lib/$$(HALCONARCH)"
win32: LIBS += halconcpp.lib

開發視覺系統,第一個要解決的小程式,恐怕就是影象在GUI上的更新了。作為一個視覺系統,不更新實時顯示,元芳你怎麼看? 定時器或執行緒手段就是用來解決這個問題的。 經過各種資料的搜刮可知,定時器方案又分為:1、QObject類的定時器, 2、定時器類QTimer。執行緒方案又有四種:1、繼承QThread、2、繼承QRunnable、3、使用moveToThread、4、使用QtConcurrent::run; 還有個小問題是,如何將圖形視窗嵌入對話方塊內。需要將halcon的 WindowHandle 同控制元件的 winId關聯起啦。 關於QObject類的定時器 QObject是所有Qt物件的基類,它提供了一個基本的定時器。 通過QObject::startTimer(),可以把一個一毫秒為單位的時間間隔作為引數來開始定時器,這個函式返回一個唯一的整數定時器的識別符號
。這個定時器開始就會在每一個時間間隔"觸發",直到明確的使用這個定時器的識別符號來呼叫QObject::killTimer()結束
    當定時器觸發時,應用程式會發送一個QTimerEvent。在事件迴圈中,處理器按照事件佇列的順序來處理定時器事件。當處理器正忙於其它事件處理時,定時器就不能立即處理。
    與定時器相關的成員函式有:startTimer()、timeEvent()、killTimer()。QObject基類中的startTimer()和timerEvent()原型及說明如下:
intQObject::startTimer(int interval);
    開始一個定時器並返回定時器ID,如果不能開始一個定時器,將返回0。定時器開始後,每隔interval毫秒間隔將觸發一次超時事件,直到killTimer()被呼叫來刪除定時器。如果interval為0,那麼定時器事件每次發生時沒有視窗系統事件處理。

virtual voidQObject::timerEvent(QTimerEvent *event);
    虛擬函式timerEvent()被過載來實現使用者的超時事件處理函式。如果有多個定時器在執行,QTimerEvent::timerId()被用來查詢指定定時器,對其進行操作。
    當定時器事件發生時,虛擬函式timerEvent()隨著QTimerEvent事件引數類一起被呼叫,過載這個函式可以獲得定時器事件。 使用該方法開啟相機步驟: 1、在UI設計器中拖入一個label,一個checkbox(continueGrabCheckBox) 2、將checkbox的訊號(clicked(bool))與widget的槽(imgGrabStartOrStop
(bool))連結 3、其他部分程式碼如下 widget.h檔案
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

#include "HalconCpp.h"
using namespace HalconCpp;

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();

protected:
    void timerEvent(QTimerEvent *);

private:
    Ui::Widget *ui;
    int imgShowTimerId;

private slots:
    void imgGrabStartOrStop(bool flag);

public:
    HObject ho_Image;
    HTuple  hv_AcqHandle;
    HTuple hv_Width, hv_Height, hv_WindosID;
    Hlong winID;
};

#endif // WIDGET_H

widget.cpp檔案
#include "widget.h"
#include "ui_widget.h"
#include<QDebug>

#define fpsOfCamera 35

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    winID = (Hlong)ui->imageShowLabel->winId();
    SetCheck("~father");
    OpenWindow(0,0,(Hlong)ui->imageShowLabel->width(),(Hlong)ui->imageShowLabel->height(),winID,"","",&hv_WindosID);
    SetCheck("father");
}

Widget::~Widget()
{
    delete ui;
}
void Widget::imgGrabStartOrStop(bool flag)
{
    if(flag)
    {
        qDebug()<<"Started grabing";
        OpenFramegrabber("DirectShow", 1, 1, 0, 0, 0, 0, "default", 8, "rgb", -1, "false",
            "default", "[0] Lenovo EasyCamera", 0, -1, &hv_AcqHandle);
        GrabImage(&ho_Image, hv_AcqHandle);
        GetImageSize(ho_Image,&hv_Width,&hv_Height);
        SetPart(hv_WindosID,0,0,hv_Height-1,hv_Width-1);
        imgShowTimerId = startTimer(1000/fpsOfCamera);
        qDebug()<<"imgShowTimerId:"<<imgShowTimerId;
    }
    else
    {
        qDebug()<<"stoped grabing! imgShowTimerId:"<<imgShowTimerId;
        killTimer(imgShowTimerId);
        CloseFramegrabber(hv_AcqHandle);
    }
}

void Widget::timerEvent(QTimerEvent *event)
{
    if(event->timerId())
    {
        GrabImage(&ho_Image, hv_AcqHandle);
        DispObj(ho_Image,hv_WindosID);
        qDebug()<<"event->timerId():"<<event->timerId();
    }
}