0

在 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;
}
4

2 回答 2

3

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

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

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

于 2014-01-30T18:25:10.683 回答
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;
    }
,...
}
于 2015-07-05T18:03:18.933 回答