如何区分opencv中的单击和双击

时间:2014-01-27 04:37:09

标签: c++ opencv highgui

在OpenCV中,双击操作似乎也会触发单击事件。这是一个示例代码。在double_click()之前总是调用single_click()。

是否可以在不首先触发single_click()的情况下触发double_click()?

谢谢!

void double_click() {
  std::cout << "Double click.\n";
}

void thisMouseCallBack(int event, int x, int y, int flags, void *param) {
  if (event == cv::EVENT_LBUTTONDOWN) {
    single_click();
  }
  if (event == cv::EVENT_LBUTTONDBLCLK) {
    double_click(); 
  }
}

int main() {
   cv::Mat testImg(100, 500, CV_8UC3); 
   cv::namedWindow("thisWindow");
   cv::setMouseCallback("thisWindow", thisMouseCallBack, NULL); 
   cv::imshow("thisWindow", testImg); 
   cv::waitKey(-1);
   return 0;
}

2 个答案:

答案 0 :(得分:3)

要区分双击和单击(即双击时仅触发双击事件,并跳过单击事件),标准方法是使用计时器。

首次点击时启动计时器(~100-200ms),但不要拨打single_click。如果计时器在收到另一次点击之前完成,请致电single_click。但是如果在计时器结束前收到另一次点击,取消计时器并拨打double_click

然而,正如Rob Kennedy上面指出的那样,这会导致一个小的延迟,所以要小心你要区分单击和双击的对象。在大多数GUI中,单击是一个选择操作,双击是一个'打开'或'执行'操作,因此在激活它之前必须选择一个对象是有意义的。

答案 1 :(得分:0)

我编写了以下代码,但它确实有用。

UINT TimerId;
int clicks;

VOID CALLBACK TimerProc(HWND hWnd, UINT nMsg, UINT nIDEvent, DWORD dwTime)
{
    KillTimer(NULL, TimerId);
    if (clicks < 2 && !double_click){
        MessageBox(hWnd, L"Show Widget", L"Widget", MB_OK);
    }

    clicks = 0;
}



LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{

    int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;
    TCHAR szHello[MAX_LOADSTRING];
    LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING);
    UINT uID;
    UINT uMouseMsg;

    uID = (UINT)wParam;
    uMouseMsg = (UINT)lParam;

    if (uMouseMsg == WM_LBUTTONDBLCLK){
        double_click = true;
        MessageBox(hWnd, L"Double click", L"CAPT", MB_OK);
        return 0;
    }
    if (uMouseMsg == WM_LBUTTONDOWN){
        double_click = false;
        clicks++;

        //single click opens context menu
        if (clicks == 1){
            TimerId = SetTimer(NULL, 0, 500, &TimerProc);
        }
        return 0;
    }
,...
}