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

0

В 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;
}
  • 1
    Двойной щелчок должен всегда вызывать одиночный щелчок; невозможно щелкнуть дважды, не щелкнув один раз, в конце концов. Альтернативой является медленное реагирование на один щелчок, потому что ваша программа должна ждать после каждого щелчка, если за ним может последовать еще один щелчок. Это заставит ваших клиентов думать, что ваша программа работает медленно. Кроме того, щелчки, как правило, не регистрируются до тех пор, пока кнопка мыши не будет отпущена, поэтому вызов вашей функции только после получения уведомления с нажатой клавишей мыши заставит вашу программу немного нервничать. Обратите особое внимание на другие программы, которые вы используете каждый день.
  • 0
    Понял. Спасибо!
Теги:
opencv
highgui

2 ответа

3

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

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

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

  • 0
    Это ответ мне нужен. Большое спасибо!
  • 0
    @ Vince Если этот ответ решил вашу проблему, вы должны принять его ( clicking на галочку слева).
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;
    }
,...
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню