Как различить щелчок и двойной щелчок в opencv

В OpenCV, кажется, действие двойного щелчка также вызывает событие одного щелчка. Вот пример кода. Single_click () всегда вызывается перед double_click().

Можно ли вызвать double_click () без предварительного запуска single_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 ответа

Чтобы различать двойные и одиночные щелчки (т. Е. Запускать только событие двойного щелчка при двойном щелчке и пропускать событие одиночного щелчка), стандартный способ сделать это использует таймер.

Запустите таймер (~100-200 мс) по первому клику, но не вызывайте single_click, Если таймер завершает работу до того, как будет получен другой щелчок, single_click, Но если еще один щелчок получен до окончания таймера, отмените таймер и вызовите double_click,

Однако, как указывает Роб Кеннеди выше, это приведет к небольшой задержке, поэтому будьте осторожны с объектами, где вы хотите различать одиночный и двойной щелчок. В большинстве графических интерфейсов один щелчок - это операция выбора, а двойной щелчок - это операция "открыть" или "выполнить", поэтому имеет смысл выбрать объект перед его активацией.

Я написал следующий код, и он работает.

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;
    }
,...
}
Другие вопросы по тегам