2014-01-27 2 views
0

В OpenCV, кажется, действие двойного щелчка также вызывает событие с одним щелчком мыши. Вот пример кода. Функция single_click() всегда вызывается перед double_click().Как различать щелчок и двойной щелчок в opencv

Возможно ли запустить 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

Получил это. Благодаря! – Vince

ответ

3

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

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

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

+0

Это тот ответ, который мне нужен. Большое спасибо! – Vince

+0

@Vince Если этот ответ решает вашу проблему, вы должны принять его (нажав галочку в левой части). – vvy

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; 
    } 
,... 
} 
Смежные вопросы