wxQueueEvent and thread Topic is solved
-
- Earned some good credits
- Posts: 138
- Joined: Tue May 20, 2008 1:03 pm
wxQueueEvent and thread
Hi,
My program display video using opencv and wxwidgets 3.0. A thread is calling cv::VideoCapture and send wxCommandEvent to main thread usind pendingEvent.
In the help file there is an example with wxQueueEvent (http://docs.wxwidgets.org/trunk/classwx_thread.html). It is written that wxQueueEvent is threadSafe but AddpendingEvent is not.
In my source code I have tried to implement wxQueueEvent but I have got errors (#define __QUEUE_EVENT__ in source file)
error C2146: erreur de syntaxe : absence de ')' avant l'identificateur 'wxEVT_COMMAND_MYTHREAD_UPDATE' in main.cpp.
Somebody can help me?
Thanks you for yours answers
My program display video using opencv and wxwidgets 3.0. A thread is calling cv::VideoCapture and send wxCommandEvent to main thread usind pendingEvent.
In the help file there is an example with wxQueueEvent (http://docs.wxwidgets.org/trunk/classwx_thread.html). It is written that wxQueueEvent is threadSafe but AddpendingEvent is not.
In my source code I have tried to implement wxQueueEvent but I have got errors (#define __QUEUE_EVENT__ in source file)
error C2146: erreur de syntaxe : absence de ')' avant l'identificateur 'wxEVT_COMMAND_MYTHREAD_UPDATE' in main.cpp.
Somebody can help me?
Thanks you for yours answers
- Attachments
-
- wxOpenCV.zip
- (6.59 KiB) Downloaded 179 times
L.B.
Re: wxQueueEvent and thread
AddPendingEvent() itself is thread-safe. As long as you only send an integer with the event like in your current code, it's safe to use it.
The only different to wxQueueEvent is, that wxQueueEvent clones the event and creates deep copies of all members, so that no problems with reference counted objects (like wxString) can occur.
The only different to wxQueueEvent is, that wxQueueEvent clones the event and creates deep copies of all members, so that no problems with reference counted objects (like wxString) can occur.
wxEVT_COMMAND_MYTHREAD_UPDATE is a custom event type that needs to be declared and defined. Did you include the two respective lines?error C2146: erreur de syntaxe : absence de ')' avant l'identificateur 'wxEVT_COMMAND_MYTHREAD_UPDATE' in main.cpp.
Code: Select all
// this can be in a header file, so that other classes can use the event type
wxDECLARE_EVENT(wxEVT_COMMAND_MYTHREAD_UPDATE, wxThreadEvent)
// this must be in a .CPP file so that it only exists once in the project
wxDEFINE_EVENT(wxEVT_COMMAND_MYTHREAD_UPDATE, wxThreadEvent)
Use the source, Luke!
Re: wxQueueEvent and thread
There it comes an example from a working project:
header.h:
implementation file .cpp
header.h:
Code: Select all
wxDECLARE_EVENT ( wxEVT_COMMAND_MYTHREAD_UPDATE,
wxThreadEvent );
class CProgressDialog : public ProgressDialog,
public wxThreadHelper {
public:
/** Constructor */
CProgressDialog ( wxWindow* parent,
wxConfig* cnfg, const wxArrayString& filenames,
int categoryIndex = 0 );
~CProgressDialog ();
bool IsOK () { return isOK; }
//// end generated class members
protected:
void OnCancel ( wxCommandEvent& event );
void OnClipboardCopy ( wxCommandEvent& event );
void OnThreadUpdate ( wxThreadEvent& event );
virtual wxThread::ExitCode Entry ();
wxDECLARE_EVENT_TABLE ();
};
implementation file .cpp
Code: Select all
wxDEFINE_EVENT ( wxEVT_COMMAND_MYTHREAD_UPDATE,
wxThreadEvent );
BEGIN_EVENT_TABLE ( CProgressDialog,
ProgressDialog )
END_EVENT_TABLE ();
CProgressDialog::CProgressDialog ( wxWindow*
parent, wxConfig* cnfg,
const wxArrayString& filenames,
int iCat )
:
ProgressDialog ( parent )
{
this->Connect ( wxEVT_COMMAND_MYTHREAD_UPDATE,
wxThreadEventHandler (
CProgressDialog::OnThreadUpdate ) );
// other code
}
CProgressDialog::~CProgressDialog ()
{
this->Disconnect ( wxEVT_COMMAND_MYTHREAD_UPDATE,
wxThreadEventHandler (
CProgressDialog::OnThreadUpdate ) );
//wxMessageBox("DESTRUCTOR");
}
wxThread::ExitCode CProgressDialog::Entry ()
{
// IMPORTANT:
// this function gets executed in the secondary thread context!
CURLM* multi_handle = curl_multi_init ();
if ( multi_handle == NULL ) {
wxThreadEvent* evt = new wxThreadEvent (
wxEVT_COMMAND_MYTHREAD_UPDATE );
evt->SetInt ( 1 );
wxQueueEvent ( this, evt );
return 0;
}
}
void CProgressDialog::OnThreadUpdate (
wxThreadEvent& event )
{
// process event here
}
The code is copy-pasted, but I hope you have a starting point now.
-
- Earned some good credits
- Posts: 138
- Joined: Tue May 20, 2008 1:03 pm
Re: wxQueueEvent and thread
Thanks you for yours answers.
PS I have found this http://wiki.wxwidgets.org/Custom_Events but I cannot compile this example
@doublemax
I have still erros
>f:\laurent\visual studio 2008\projects\wxopencv\wxopencv\main.cpp(46): warning C4003: nombre de paramètres réels insuffisants pour la macro 'EVT_COMMAND'
1>f:\laurent\visual studio 2008\projects\wxopencv\wxopencv\main.cpp(46): warning C4003: nombre de paramètres réels insuffisants pour la macro 'wxCommandEventHandler'
1>f:\laurent\visual studio 2008\projects\wxopencv\wxopencv\main.cpp(46): error C2146: erreur de syntaxe : absence de ')' avant l'identificateur 'wxEVT_COMMAND_MYTHREAD_UPDATE'
1>f:\laurent\visual studio 2008\projects\wxopencv\wxopencv\main.cpp(46): error C2661: 'wxEventTableEntry::wxEventTableEntry' : aucune fonction surchargée ne nécessite 2 arguments
If I write in main.cpp
#define __QUEUE_EVENT__
#ifdef __QUEUE_EVENT__
wxDECLARE_EVENT(wxEVT_COMMAND_MYTHREAD_UPDATE, wxThreadEvent);
wxDEFINE_EVENT(wxEVT_COMMAND_MYTHREAD_UPDATE, wxThreadEvent);
#endif
// --------------------------------------------------------------------------
// Table des évènements
// --------------------------------------------------------------------------
wxBEGIN_EVENT_TABLE(IHMOpenCV, wxFrame)
EVT_MENU(IHMOpenCV_QUIT, IHMOpenCV::OnQuit)
EVT_MENU(IHMOpenCV_APROPOS, IHMOpenCV::OnAbout)
EVT_MENU(IHMOpenCV_DBACQ, IHMOpenCV::DebutAcq)
EVT_COMMAND(28, wxEVT_COMMAND_TEXT_UPDATED, IHMOpenCV::OnThreadUpdate)
#ifdef __QUEUE_EVENT__
EVT_COMMAND(wxID_ANY wxEVT_COMMAND_MYTHREAD_UPDATE, IHMOpenCV::OnThreadUpdateQueue) // LINE 46
#endif
EVT_TIMER(wxID_ANY,IHMOpenCV::OnTimerEvent)
wxEND_EVENT_TABLE()
@modoran in your example source abd destination is the same class I think
PS I have found this http://wiki.wxwidgets.org/Custom_Events but I cannot compile this example
@doublemax
I have still erros
>f:\laurent\visual studio 2008\projects\wxopencv\wxopencv\main.cpp(46): warning C4003: nombre de paramètres réels insuffisants pour la macro 'EVT_COMMAND'
1>f:\laurent\visual studio 2008\projects\wxopencv\wxopencv\main.cpp(46): warning C4003: nombre de paramètres réels insuffisants pour la macro 'wxCommandEventHandler'
1>f:\laurent\visual studio 2008\projects\wxopencv\wxopencv\main.cpp(46): error C2146: erreur de syntaxe : absence de ')' avant l'identificateur 'wxEVT_COMMAND_MYTHREAD_UPDATE'
1>f:\laurent\visual studio 2008\projects\wxopencv\wxopencv\main.cpp(46): error C2661: 'wxEventTableEntry::wxEventTableEntry' : aucune fonction surchargée ne nécessite 2 arguments
If I write in main.cpp
#define __QUEUE_EVENT__
#ifdef __QUEUE_EVENT__
wxDECLARE_EVENT(wxEVT_COMMAND_MYTHREAD_UPDATE, wxThreadEvent);
wxDEFINE_EVENT(wxEVT_COMMAND_MYTHREAD_UPDATE, wxThreadEvent);
#endif
// --------------------------------------------------------------------------
// Table des évènements
// --------------------------------------------------------------------------
wxBEGIN_EVENT_TABLE(IHMOpenCV, wxFrame)
EVT_MENU(IHMOpenCV_QUIT, IHMOpenCV::OnQuit)
EVT_MENU(IHMOpenCV_APROPOS, IHMOpenCV::OnAbout)
EVT_MENU(IHMOpenCV_DBACQ, IHMOpenCV::DebutAcq)
EVT_COMMAND(28, wxEVT_COMMAND_TEXT_UPDATED, IHMOpenCV::OnThreadUpdate)
#ifdef __QUEUE_EVENT__
EVT_COMMAND(wxID_ANY wxEVT_COMMAND_MYTHREAD_UPDATE, IHMOpenCV::OnThreadUpdateQueue) // LINE 46
#endif
EVT_TIMER(wxID_ANY,IHMOpenCV::OnTimerEvent)
wxEND_EVENT_TABLE()
@modoran in your example source abd destination is the same class I think
L.B.
-
- Earned some good credits
- Posts: 138
- Joined: Tue May 20, 2008 1:03 pm
Re: wxQueueEvent and thread
I forget a comma in
EVT_COMMAND(wxID_ANY,wxEVT_COMMAND_MYTHREAD_UPDATE, IHMOpenCV::OnThreadUpdateQueue)
but there is still an error :
error C2440: 'static_cast' : impossible de convertir de 'void (__thiscall IHMOpenCV::* )(wxThreadEvent &)' en 'wxCommandEventFunction'
EVT_COMMAND(wxID_ANY,wxEVT_COMMAND_MYTHREAD_UPDATE, IHMOpenCV::OnThreadUpdateQueue)
but there is still an error :
error C2440: 'static_cast' : impossible de convertir de 'void (__thiscall IHMOpenCV::* )(wxThreadEvent &)' en 'wxCommandEventFunction'
L.B.
Re: wxQueueEvent and thread
Change IHMOpenCV::OnThreadUpdateQueue to take wxThreadEvent instead of wxCommandEvent as parameter.
Use the source, Luke!
-
- Earned some good credits
- Posts: 138
- Joined: Tue May 20, 2008 1:03 pm
Re: wxQueueEvent and thread
already done in my code.doublemax wrote:Change IHMOpenCV::OnThreadUpdateQueue to take wxThreadEvent instead of wxCommandEvent as parameter.
My code is a copy of this example (http://docs.wxwidgets.org/trunk/classwx_thread.html) where you can find this two lines :
EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_MYTHREAD_UPDATE, MyFrame::OnThreadUpdate)
wxDECLARE_EVENT(wxEVT_COMMAND_MYTHREAD_UPDATE, wxThreadEvent); I don't understand how a commandEvent and threadevent can be similar
Code: Select all
// declare a new type of event, to be used by our MyThread class:
wxDECLARE_EVENT(wxEVT_COMMAND_MYTHREAD_COMPLETED, wxThreadEvent);
wxDECLARE_EVENT(wxEVT_COMMAND_MYTHREAD_UPDATE, wxThreadEvent);
class MyFrame;
class MyThread : public wxThread
{
public:
MyThread(MyFrame *handler)
: wxThread(wxTHREAD_DETACHED)
{ m_pHandler = handler }
~MyThread();
protected:
virtual ExitCode Entry();
MyFrame *m_pHandler;
};
class MyFrame : public wxFrame
{
public:
...
~MyFrame()
{
// it's better to do any thread cleanup in the OnClose()
// event handler, rather than in the destructor.
// This is because the event loop for a top-level window is not
// active anymore when its destructor is called and if the thread
// sends events when ending, they won't be processed unless
// you ended the thread from OnClose.
// See @ref overview_windowdeletion for more info.
}
...
void DoStartThread();
void DoPauseThread();
// a resume routine would be nearly identic to DoPauseThread()
void DoResumeThread() { ... }
void OnThreadUpdate(wxThreadEvent&);
void OnThreadCompletion(wxThreadEvent&);
void OnClose(wxCloseEvent&);
protected:
MyThread *m_pThread;
wxCriticalSection m_pThreadCS; // protects the m_pThread pointer
friend class MyThread; // allow it to access our m_pThread
wxDECLARE_EVENT_TABLE();
};
wxBEGIN_EVENT_TABLE(MyFrame, wxFrame)
EVT_CLOSE(MyFrame::OnClose)
EVT_MENU(Minimal_Start, MyFrame::DoStartThread)
EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_MYTHREAD_UPDATE, MyFrame::OnThreadUpdate)
EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_MYTHREAD_COMPLETED, MyFrame::OnThreadCompletion)
wxEND_EVENT_TABLE()
wxDEFINE_EVENT(wxEVT_COMMAND_MYTHREAD_COMPLETED, wxThreadEvent)
wxDEFINE_EVENT(wxEVT_COMMAND_MYTHREAD_UPDATE, wxThreadEvent)
void MyFrame::DoStartThread()
{
m_pThread = new MyThread(this);
if ( m_pThread->Run() != wxTHREAD_NO_ERROR )
{
wxLogError("Can't create the thread!");
delete m_pThread;
m_pThread = NULL;
}
// after the call to wxThread::Run(), the m_pThread pointer is "unsafe":
// at any moment the thread may cease to exist (because it completes its work).
// To avoid dangling pointers OnThreadExit() will set m_pThread
// to NULL when the thread dies.
}
wxThread::ExitCode MyThread::Entry()
{
while (!TestDestroy())
{
// ... do a bit of work...
wxQueueEvent(m_pHandler, new wxThreadEvent(wxEVT_COMMAND_MYTHREAD_UPDATE));
}
// signal the event handler that this thread is going to be destroyed
// NOTE: here we assume that using the m_pHandler pointer is safe,
// (in this case this is assured by the MyFrame destructor)
wxQueueEvent(m_pHandler, new wxThreadEvent(wxEVT_COMMAND_MYTHREAD_COMPLETED));
return (wxThread::ExitCode)0; // success
}
MyThread::~MyThread()
{
wxCriticalSectionLocker enter(m_pHandler->m_pThreadCS);
// the thread is being destroyed; make sure not to leave dangling pointers around
m_pHandler->m_pThread = NULL;
}
void MyFrame::OnThreadCompletion(wxThreadEvent&)
{
wxMessageOutputDebug().Printf("MYFRAME: MyThread exited!\n");
}
void MyFrame::OnThreadUpdate(wxThreadEvent&)
{
wxMessageOutputDebug().Printf("MYFRAME: MyThread update...\n");
}
void MyFrame::DoPauseThread()
{
// anytime we access the m_pThread pointer we must ensure that it won't
// be modified in the meanwhile; since only a single thread may be
// inside a given critical section at a given time, the following code
// is safe:
wxCriticalSectionLocker enter(m_pThreadCS);
if (m_pThread) // does the thread still exist?
{
// without a critical section, once reached this point it may happen
// that the OS scheduler gives control to the MyThread::Entry() function,
// which in turn may return (because it completes its work) making
// invalid the m_pThread pointer
if (m_pThread->Pause() != wxTHREAD_NO_ERROR )
wxLogError("Can't pause the thread!");
}
}
void MyFrame::OnClose(wxCloseEvent&)
{
{
wxCriticalSectionLocker enter(m_pThreadCS);
if (m_pThread) // does the thread still exist?
{
wxMessageOutputDebug().Printf("MYFRAME: deleting thread");
if (m_pThread->Delete() != wxTHREAD_NO_ERROR )
wxLogError("Can't delete the thread!");
}
} // exit from the critical section to give the thread
// the possibility to enter its destructor
// (which is guarded with m_pThreadCS critical section!)
while (1)
{
{ // was the ~MyThread() function executed?
wxCriticalSectionLocker enter(m_pThreadCS);
if (!m_pThread) break;
}
// wait for thread completion
wxThread::This()->Sleep(1);
}
Destroy();
}
L.B.
Re: wxQueueEvent and thread
Code: Select all
EVT_COMMAND(wxID_ANY, wxEVT_COMMAND_MYTHREAD_UPDATE, MyFrame::OnThreadUpdate)
Use the source, Luke!
-
- Earned some good credits
- Posts: 138
- Joined: Tue May 20, 2008 1:03 pm
Re: wxQueueEvent and thread
the source code now is for IMHVideoimage.cpp
and for main.cpp
and I can see video with 30 frames per second. But I have to say that I had modified :
wxQueueEvent( parent->GetEventHandler(), new wxThreadEvent(wxEVT_THREAD,wxEVT_COMMAND_MYTHREAD_UPDATE));
in
wxQueueEvent( parent->GetEventHandler(), new wxThreadEvent(wxEVT_THREAD,1+(int)wxEVT_COMMAND_MYTHREAD_UPDATE));
The reason is written in http://wiki.wxwidgets.org/Custom_Events :
Code: Select all
#include "IHMVideoImage.h"
wxBEGIN_EVENT_TABLE(IHMVideoImage, wxFrame)
EVT_ERASE_BACKGROUND(IHMVideoImage::OnEraseBackground)
EVT_PAINT(IHMVideoImage::OnPaint)
EVT_CLOSE(IHMVideoImage::OnClose)
EVT_MENU(wxID_ZOOM_IN, IHMVideoImage::OnZoom)
EVT_MENU(wxID_ZOOM_OUT, IHMVideoImage::OnZoom)
EVT_MENU(wxID_ZOOM_100, IHMVideoImage::OnZoom)
wxEND_EVENT_TABLE()
#define __QUEUE_EVENT__
#ifdef __QUEUE_EVENT__
wxDEFINE_EVENT(wxEVT_COMMAND_MYTHREAD_UPDATE, wxThreadEvent);
#endif
#include "wxOpenCV.h"
#include "opencv2/opencv.hpp"
using namespace cv;
wxThread::ExitCode CaptureVideo::Entry()
{
#ifdef __QUEUE_EVENT__
int i=wxEVT_COMMAND_MYTHREAD_UPDATE;
#endif
cap= new VideoCapture(0);
if(!cap->isOpened()) // check if we succeeded
return (wxThread::ExitCode)0;
Mat edges;
for(;!TestDestroy();)
{
Mat frame;
(*cap) >> frame; // get a new frame from camera
accesBitmap.Lock();
unsigned char *pImage=image->GetData();
unsigned char *pFrame=frame.data;
int pasLigne=frame.step;
for (int i=0;i<frame.rows;i++,pFrame+=pasLigne)
{
unsigned char *p=pFrame;
for (int j=0;j<frame.cols;j++)
{
pImage[2]=*p++;
pImage[1]=*p++;
pImage[0]=*p++;
pImage+=3;
}
}
accesBitmap.Unlock();
#ifdef __QUEUE_EVENT__
wxQueueEvent( parent->GetEventHandler(), new wxThreadEvent(wxEVT_THREAD,1+(int)wxEVT_COMMAND_MYTHREAD_UPDATE));
#else
wxCommandEvent *evt = new wxCommandEvent( wxEVT_COMMAND_TEXT_UPDATED, 28 );
evt->SetInt(39); // pass some data along the event, a number in this case
parent->GetEventHandler()->AddPendingEvent( *evt );
#endif
}
delete cap;
cap=NULL;
return (wxThread::ExitCode)0;
}
Code: Select all
#include "wxOpenCV.h"
#include "opencv2/opencv.hpp"
#include <opencv/highgui.h>
#include "IHMImage.h"
#include "IHMVideoImage.h"
#include <fstream>
#include <map>
using namespace cv;
using namespace std;
enum
{
// Identifiant des menus
IHMOpenCV_QUIT = wxID_EXIT,
IHMOpenCV_APROPOS = wxID_ABOUT,
IHMOpenCV_DBACQ
};
#define __QUEUE_EVENT__
#ifdef __QUEUE_EVENT__
wxDECLARE_EVENT(wxEVT_COMMAND_MYTHREAD_UPDATE, wxThreadEvent);
wxDEFINE_EVENT(wxEVT_COMMAND_MYTHREAD_UPDATE, wxThreadEvent);
#endif
// --------------------------------------------------------------------------
// Table des évènements
// --------------------------------------------------------------------------
wxBEGIN_EVENT_TABLE(IHMOpenCV, wxFrame)
EVT_MENU(IHMOpenCV_QUIT, IHMOpenCV::OnQuit)
EVT_MENU(IHMOpenCV_APROPOS, IHMOpenCV::OnAbout)
EVT_COMMAND(28, wxEVT_COMMAND_TEXT_UPDATED, IHMOpenCV::OnThreadUpdate)
EVT_MENU(IHMOpenCV_DBACQ, IHMOpenCV::DebutAcq)
#ifdef __QUEUE_EVENT__
EVT_THREAD(wxEVT_COMMAND_MYTHREAD_UPDATE, IHMOpenCV::OnThreadUpdateQueue)
#endif
EVT_TIMER(wxID_ANY,IHMOpenCV::OnTimerEvent)
wxEND_EVENT_TABLE()
IMPLEMENT_APP(wxOpenCV)
void IHMOpenCV::OnThreadUpdateQueue(wxThreadEvent &w)
{
// Une nouvelle image doit être affichée
if (!imageVideo)
return;
nbImageParSeconde++;
// Blocage de l'accés par wxMutex à la mémoire de l'image
imageVideo->accesBitmap.Lock();
// affichage de l'image
ecranVideo->Draw(imageVideo->image);
// Libére l'accès à la mémoire
imageVideo->accesBitmap.Unlock();
}
wxQueueEvent( parent->GetEventHandler(), new wxThreadEvent(wxEVT_THREAD,wxEVT_COMMAND_MYTHREAD_UPDATE));
in
wxQueueEvent( parent->GetEventHandler(), new wxThreadEvent(wxEVT_THREAD,1+(int)wxEVT_COMMAND_MYTHREAD_UPDATE));
The reason is written in http://wiki.wxwidgets.org/Custom_Events :
How avoid this? call a method that will be the good value for the event handler...What could possibly go wrong?
You must define the wxEventType exactly once. If you add wxDEFINE_EVENT(MY_NEW_TYPE, wxCommandEvent); to two files, it will be defined twice with two different values. The same thing will happen if you write it only once, but you put it in a header file that is #included more than once. Why does that matter? Because you'll be posting an event with the type (e.g.) 12000, and trying to catch events with type 12001; which will silently fail.
L.B.
Re: wxQueueEvent and thread
Like i wrote in a previous post, the wxDEFINE_EVENT(...) line must exist only once and in a .CPP file.
Use the source, Luke!
-
- Earned some good credits
- Posts: 138
- Joined: Tue May 20, 2008 1:03 pm
Re: wxQueueEvent and thread
Thanks !
you are right Everything is Ok now
in main.cpp :
and in IHMVideoImage.cpp
you are right Everything is Ok now
in main.cpp :
Code: Select all
#include "opencv2/opencv.hpp"
#include <opencv/highgui.h>
#include "IHMImage.h"
#include "IHMVideoImage.h"
#include <fstream>
#include <map>
using namespace cv;
using namespace std;
enum
{
// Identifiant des menus
IHMOpenCV_QUIT = wxID_EXIT,
IHMOpenCV_APROPOS = wxID_ABOUT,
IHMOpenCV_DBACQ
};
wxDECLARE_EVENT(wxEVT_COMMAND_MYTHREAD_UPDATE, wxThreadEvent);
wxDEFINE_EVENT(wxEVT_COMMAND_MYTHREAD_UPDATE, wxThreadEvent);
// --------------------------------------------------------------------------
// Table des évènements
// --------------------------------------------------------------------------
wxBEGIN_EVENT_TABLE(IHMOpenCV, wxFrame)
EVT_MENU(IHMOpenCV_QUIT, IHMOpenCV::OnQuit)
EVT_MENU(IHMOpenCV_APROPOS, IHMOpenCV::OnAbout)
EVT_MENU(IHMOpenCV_DBACQ, IHMOpenCV::DebutAcq)
EVT_THREAD(wxEVT_COMMAND_MYTHREAD_UPDATE, IHMOpenCV::OnThreadUpdateQueue)
EVT_TIMER(wxID_ANY,IHMOpenCV::OnTimerEvent)
wxEND_EVENT_TABLE()
IMPLEMENT_APP(wxOpenCV)
void IHMOpenCV::OnThreadUpdateQueue(wxThreadEvent &w)
{
// Une nouvelle image doit être affichée
if (!imageVideo)
return;
nbImageParSeconde++;
// Blocage de l'accés par wxMutex à la mémoire de l'image
imageVideo->accesBitmap.Lock();
// affichage de l'image
ecranVideo->Draw(imageVideo->image);
// Libére l'accès à la mémoire
imageVideo->accesBitmap.Unlock();
}
Code: Select all
#include "IHMVideoImage.h"
wxBEGIN_EVENT_TABLE(IHMVideoImage, wxFrame)
EVT_ERASE_BACKGROUND(IHMVideoImage::OnEraseBackground)
EVT_PAINT(IHMVideoImage::OnPaint)
EVT_CLOSE(IHMVideoImage::OnClose)
EVT_MENU(wxID_ZOOM_IN, IHMVideoImage::OnZoom)
EVT_MENU(wxID_ZOOM_OUT, IHMVideoImage::OnZoom)
EVT_MENU(wxID_ZOOM_100, IHMVideoImage::OnZoom)
wxEND_EVENT_TABLE()
wxDECLARE_EVENT(wxEVT_COMMAND_MYTHREAD_UPDATE, wxThreadEvent);
#include "wxOpenCV.h"
#include "opencv2/opencv.hpp"
using namespace cv;
wxThread::ExitCode CaptureVideo::Entry()
{
cap= new VideoCapture(0);
if(!cap->isOpened()) // check if we succeeded
return (wxThread::ExitCode)0;
Mat edges;
for(;!TestDestroy();)
{
Mat frame;
(*cap) >> frame; // get a new frame from camera
accesBitmap.Lock();
unsigned char *pImage=image->GetData();
unsigned char *pFrame=frame.data;
int pasLigne=frame.step;
for (int i=0;i<frame.rows;i++,pFrame+=pasLigne)
{
unsigned char *p=pFrame;
for (int j=0;j<frame.cols;j++)
{
pImage[2]=*p++;
pImage[1]=*p++;
pImage[0]=*p++;
pImage+=3;
}
}
accesBitmap.Unlock();
wxQueueEvent( parent->GetEventHandler(), new wxThreadEvent(wxEVT_THREAD,wxEVT_COMMAND_MYTHREAD_UPDATE));
}
delete cap;
cap=NULL;
return (wxThread::ExitCode)0;
}
L.B.