I'd like to understand how to use cv::createButton which is defined in OpenCV documentation:
http://opencv.jp/opencv-2svn_org/cpp/highgui_qt_new_functions.html#cv-createbutton
It says that the prototype is:
createButton(const string& button_name CV_DEFAULT(NULL), ButtonCallback on_change CV_DEFAULT(NULL), void* userdata CV_DEFAULT(NULL), int button_type CV_DEFAULT(CV_PUSH_BUTTON), int initial_button_state CV_DEFAULT(0)
but i don't know how to define the function ButtonCallback in order to trap the button event.
I do:
cvCreateButton("button6", callbackButton2, pointer, CV_PUSH_BUTTON, 0);
to declare the button and
void callbackButton2(int state, void *pointer){
printf("ok");
}
but it doesn't work.
I don't know the meaning of the third parameter "void* userdata".
Can someone help me, please?
Thanks.
We still don't know what doesn't work means to you, but I'll provide some information on how to use the callback and what userdata is.
As the signature suggests, void* userdata is a parameter that you can use to send/receive data to the callback. This is purely optional, so if you don't have any use for it just pass NULL.
On the example below I'll be using userdata to retrieve data from the callback. You might have noticed that the callback receives a state information from OpenCV. I'm interested in storing this value and making it available to main().
For this purpose, I define a custom data type and declare a variable of this type on main(). The custom type has an int member to store the state received by our callback and a mutex that we are going to use to protect the custom type from being read/written simultaneously by the 2 threads (callback and main()).
#include <iostream>
#include <cv.h>
#include <highgui.h>
#include <pthread.h>
#include <string.h>
using namespace cv;
typedef struct custom_data
{
int state;
pthread_mutex_t mtx;
} custom_data_t;
void my_button_cb(int state, void* userdata)
{
std::cout << "@my_button_cb" << std::endl;
// convert userdata to the right type
custom_data_t* ptr = (custom_data_t*)userdata;
if (!ptr)
{
std::cout << "@my_button_cb userdata is empty" << std::endl;
return;
}
// lock mutex to protect data from being modified by the
// main() thread
pthread_mutex_lock(&ptr->mtx);
ptr->state = state;
// unlock mutex
pthread_mutex_unlock(&ptr->mtx);
}
int main()
{
// declare and initialize our userdata
custom_data_t my_data = { 0 };
createButton("dummy_button", my_button_cb, &my_data, CV_PUSH_BUTTON, 0);
// For testing purposes, go ahead and click the button to activate
// our callback.
// waiting for key press <enter> on the console to continue the execution
getchar();
// At this point the button exists, and our callback was called
// (if you clicked the button). In a real application, the button is
// probably going to be pressed again, and again, so we need to protect
// our data from being modified while we are accessing it.
pthread_mutex_lock(&my_data.mtx);
std::cout << "The state retrieved by the callback is: " << my_data.state << std::endl;
// unlock mutex
pthread_mutex_unlock(&my_data.mtx);
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With