Fork me on GitHub

10/26/2010

封裝 openCV 事件成物件的方法成員 - event encapsulation

在使用 openCV 提供的 highgui 時,其提供了一個簡單的滑鼠鍵盤事件機制,透過 cvSetMouseCallback 將 on_mouse 事件綁定到 window_name 視窗。



CVAPI(void) cvSetMouseCallback( const char* window_name, CvMouseCallback on_mousevoid* param CV_DEFAULT(NULL));


一旦 window_name 視窗發生動作就會驅動 on_mouse 事件方法,但是這個 on_mouse 方法不能是類別的方法成員 ( 例:object->on_mouse ),嘗試後發現,可以利用函數指標將 on_mouse 方法 assign 成 object 的函數指標成員,這樣就可以成功的將事件方法封裝到類別之中。


// ctrl.h

typedef void (*pFun)(int, int, int, int, void*);

class Controller {
public:
  Controller();

  pFun pFun1;
};



// ctrl.cpp

#include <iostream>
#include <highgui.h>
#include "ctrl.h"

void on_mouse( int event, int x, int y, int flags, void *param )
{   
  if( event == CV_EVENT_LBUTTONDOWN )
    std::cout << "LBUTTONDOWN  occurs in the window" << std::endl
}

Controller::Controller()
{
  pFun1 = &on_mouse;
}



// main.cpp

#include <highgui.h>
#include "ctrl.h"

int main()
{

  Controller controller;

  cvNamedWindow("src", 1);
  cvSetMouseCallback( "src", controller.pFun1, 0 );

  while(1) {
    int c = cvWaitKey(30);
    if ( (char)c == 27 ) {
      cvDestroyWindow( "src" );     
      break;     
    }
  }
}


實作之後發現,此法依舊行不通,單純的函式指標 (如上) ok。但是,成員函式指標 依然無法 work,最後的解決辦法是將 on_mouse 變成一個 cpp 的全域變數,然後再用 friend 使其可以存取類別的私有成員...

...

No comments:

Post a Comment