From 21026bf7cdfcd2adecb656ca66359f0fac4edb7c Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Thu, 19 Apr 2018 18:42:01 +0300 Subject: [PATCH] python: fix support of UI callbacks --- modules/python/src2/cv2.cpp | 58 +++++++++++++++++++++++++------------ 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/modules/python/src2/cv2.cpp b/modules/python/src2/cv2.cpp index 7d55513315..2c2e9ecf61 100644 --- a/modules/python/src2/cv2.cpp +++ b/modules/python/src2/cv2.cpp @@ -27,6 +27,7 @@ #include "pycompat.hpp" +#include static PyObject* opencv_error = 0; @@ -1621,13 +1622,19 @@ static PyObject *pycvSetMouseCallback(PyObject*, PyObject *args, PyObject *kw) if (param == NULL) { param = Py_None; } - static PyObject* last_param = NULL; - if (last_param) { - Py_DECREF(last_param); - last_param = NULL; + PyObject* py_callback_info = Py_BuildValue("OO", on_mouse, param); + static std::map registered_callbacks; + std::map::iterator i = registered_callbacks.find(name); + if (i != registered_callbacks.end()) + { + Py_DECREF(i->second); + i->second = py_callback_info; + } + else + { + registered_callbacks.insert(std::pair(std::string(name), py_callback_info)); } - last_param = Py_BuildValue("OO", on_mouse, param); - ERRWRAP2(setMouseCallback(name, OnMouse, last_param)); + ERRWRAP2(setMouseCallback(name, OnMouse, py_callback_info)); Py_RETURN_NONE; } #endif @@ -1663,13 +1670,20 @@ static PyObject *pycvCreateTrackbar(PyObject*, PyObject *args) PyErr_SetString(PyExc_TypeError, "on_change must be callable"); return NULL; } - static PyObject* last_param = NULL; - if (last_param) { - Py_DECREF(last_param); - last_param = NULL; + PyObject* py_callback_info = Py_BuildValue("OO", on_change, Py_None); + std::string name = std::string(window_name) + ":" + std::string(trackbar_name); + static std::map registered_callbacks; + std::map::iterator i = registered_callbacks.find(name); + if (i != registered_callbacks.end()) + { + Py_DECREF(i->second); + i->second = py_callback_info; } - last_param = Py_BuildValue("OO", on_change, Py_None); - ERRWRAP2(createTrackbar(trackbar_name, window_name, value, count, OnChange, last_param)); + else + { + registered_callbacks.insert(std::pair(name, py_callback_info)); + } + ERRWRAP2(createTrackbar(trackbar_name, window_name, value, count, OnChange, py_callback_info)); Py_RETURN_NONE; } @@ -1717,13 +1731,21 @@ static PyObject *pycvCreateButton(PyObject*, PyObject *args, PyObject *kw) userdata = Py_None; } - static PyObject* last_param = NULL; - if (last_param) { - Py_DECREF(last_param); - last_param = NULL; + PyObject* py_callback_info = Py_BuildValue("OO", on_change, userdata); + std::string name(button_name); + + static std::map registered_callbacks; + std::map::iterator i = registered_callbacks.find(name); + if (i != registered_callbacks.end()) + { + Py_DECREF(i->second); + i->second = py_callback_info; + } + else + { + registered_callbacks.insert(std::pair(name, py_callback_info)); } - last_param = Py_BuildValue("OO", on_change, userdata); - ERRWRAP2(createButton(button_name, OnButtonChange, last_param, button_type, initial_button_state != 0)); + ERRWRAP2(createButton(button_name, OnButtonChange, py_callback_info, button_type, initial_button_state != 0)); Py_RETURN_NONE; } #endif