如何区分OpenCV中的点击和双击

How to distinguish between click and double-click in opencv

本文关键字:双击 何区 OpenCV      更新时间:2023-10-16

在OpenCV中,似乎是双击动作也触发了一个单击事件。这是示例代码。single_click()始终在double_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;
}

以区分双击和单击(即双击双击的双击事件,然后跳过单击事件),使用计时器的标准方法。p>首次单击时启动计时器(〜100-200ms),但请勿致电single_click。如果计时器在收到另一键之前完成,请致电single_click。但是,如果在计时器完成之前收到另一键,请取消计时器并致电double_click

但是,正如罗布·肯尼迪(Rob Kennedy)上面指出的那样,这将导致较小的延迟,因此请谨慎对象要区分单击和双击。在大多数GUI中,单击是一个选择操作,双击是"打开"或"执行"操作,因此必须在激活它之前选择对象是很有意义的。

我编写了以下代码,并且有效。

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;
    }
,...
}