wxWidget实现连续绘图并能够控制绘图的开始与结束

在用CCD相机拍照的图像进行实时成像的时候遇到这么一个问题:

   1: RunCamera();
   2: while (1) {
   3:     GetImg();
   4:     ShowImg();
   5: }
   6: CloseCamera();

想要对获取的图像进行实时成像,最先想到的是采用while(1)的方式,但是这样的方式会带来一些问题,除了终止程序,没有办法使得循环停下,这个结果不是我们想要的。如果加上一个i < 100类似的条件,数量太大需要等,数量太小很快就结束了。我们想要设计的是能够随叫随停的,能够控制成像与停止的功能。

第一个想到的是onTimer的方式进行实现,不过水平低低,还是先在网上搜索一翻吧,功夫不负有心人,还是找到了。Making a render loop

它采用了两种方式,一种为事件处理方式,一种为刚想到的onTimer的方式。下面参考上述链接中的内容,同时考虑自己的功能需求,给出了自己实现的具体代码。

所有的代码都是在codeblock下实现的。

1. 事件处理方式

采用onIdel的方式,一种频率最快的方式之一;但是频率不是固定的,当你进行其它操作时,如打开菜单Idel将会停止处理。

   1: // the most improtant code in frame.h and frame.cpp
   2: /***************************************************************
   3:  * Name:      tmp1Main.h
   4:  * Purpose:   Defines Application Frame
   5:  * Author:    grass in moon 
   6:  * Created:   2012-07-06
   7:  * Copyright: grass in moon (http://www.cppblog.com/grass-and-moon/)
   8:  * License:
   9:  **************************************************************/
  10:  
  11: #ifndef TMP1MAIN_H
  12: #define TMP1MAIN_H
  13:  
  14: #ifndef WX_PRECOMP
  15: #include <wx/wx.h>
  16: #endif
  17:  
  18: #include "tmp1App.h"
  19:  
  20: class tmp1Frame: public wxFrame
  21: {
  22: public:
  23:     tmp1Frame(wxFrame *frame, const wxString& title);
  24:     ~tmp1Frame();
  25:  
  26:     // for painting
  27:     void PaintNow();
  28:     void render(wxDC& dc);
  29:  
  30: private:
  31:     enum
  32:     {
  33:         idMenuQuit = 1000,
  34:         idMenuAbout,
  35:         idStartLoop,
  36:         idStopLoop
  37:     };
  38:  
  39:     // mark loop on or off
  40:     bool render_loop_on;
  41:  
  42:     void OnClose(wxCloseEvent& event);
  43:     void OnQuit(wxCommandEvent& event);
  44:     void OnAbout(wxCommandEvent& event);
  45:     void OnStartLoop(wxCommandEvent& event);
  46:     void OnStopLoop(wxCommandEvent& event);
  47:  
  48:     // deel with wxIdleEvent
  49:     void OnIdle(wxIdleEvent& event);
  50:  
  51:     DECLARE_EVENT_TABLE()
  52: };
  53:  
  54:  
  55: #endif // TMP1MAIN_H
  56:  
  57: /***************************************************************
  58:  * Name:      tmp1Main.cpp
  59:  * Purpose:   Code for Application Frame
  60:  * Author:    grass in moon
  61:  * Created:   2012-07-06
  62:  * Copyright: grass in moon (http://www.cppblog.com/grass-and-moon/)
  63:  * License:
  64:  **************************************************************/
  65:  
  66: #ifdef WX_PRECOMP
  67: #include "wx_pch.h"
  68: #endif
  69:  
  70: #ifdef __BORLANDC__
  71: #pragma hdrstop
  72: #endif //__BORLANDC__
  73:  
  74: #include "tmp1Main.h"
  75:  
  76: //helper functions
  77: enum wxbuildinfoformat
  78: {
  79:     short_f, long_f
  80: };
  81:  
  82: wxString wxbuildinfo(wxbuildinfoformat format)
  83: {
  84:     wxString wxbuild(wxVERSION_STRING);
  85:  
  86:     if (format == long_f )
  87:     {
  88: #if defined(__WXMSW__)
  89:         wxbuild << _T("-Windows");
  90: #elif defined(__WXMAC__)
  91:         wxbuild << _T("-Mac");
  92: #elif defined(__UNIX__)
  93:         wxbuild << _T("-Linux");
  94: #endif
  95:  
  96: #if wxUSE_UNICODE
  97:         wxbuild << _T("-Unicode build");
  98: #else
  99:         wxbuild << _T("-ANSI build");
 100: #endif // wxUSE_UNICODE
 101:     }
 102:  
 103:     return wxbuild;
 104: }
 105:  
 106: BEGIN_EVENT_TABLE(tmp1Frame, wxFrame)
 107:     EVT_CLOSE(tmp1Frame::OnClose)
 108:     EVT_MENU(idMenuQuit, tmp1Frame::OnQuit)
 109:     EVT_MENU(idMenuAbout, tmp1Frame::OnAbout)
 110:     EVT_MENU(idStartLoop, tmp1Frame::OnStartLoop)
 111:     EVT_MENU(idStopLoop, tmp1Frame::OnStopLoop)
 112:     EVT_IDLE(tmp1Frame::OnIdle)
 113: END_EVENT_TABLE()
 114:  
 115: tmp1Frame::tmp1Frame(wxFrame *frame, const wxString& title)
 116:     : wxFrame(frame, -1, title)
 117: {
 118: #if wxUSE_MENUS
 119:     // create a menu bar
 120:     wxMenuBar* mbar = new wxMenuBar();
 121:     wxMenu* fileMenu = new wxMenu(_T(""));
 122:     fileMenu->Append(idMenuQuit, _("&Quit\tAlt-F4"), _("Quit the application"));
 123:     fileMenu->Append(idStartLoop, _("St&artLoop"));       // for starting draw text
 124:     fileMenu->Append(idStopLoop, _("Sto&pLoop"));         // for stoping draw text
 125:     mbar->Append(fileMenu, _("&File"));
 126:  
 127:     wxMenu* helpMenu = new wxMenu(_T(""));
 128:     helpMenu->Append(idMenuAbout, _("&About\tF1"), _("Show info about this application"));
 129:     mbar->Append(helpMenu, _("&Help"));
 130:  
 131:     SetMenuBar(mbar);
 132: #endif // wxUSE_MENUS
 133:  
 134: #if wxUSE_STATUSBAR
 135:     // create a status bar with some information about the used wxWidgets version
 136:     CreateStatusBar(2);
 137:     SetStatusText(_("Hello Code::Blocks user!"),0);
 138:     SetStatusText(wxbuildinfo(short_f), 1);
 139: #endif // wxUSE_STATUSBAR
 140:  
 141:     render_loop_on = false;
 142: }
 143:  
 144:  
 145: tmp1Frame::~tmp1Frame()
 146: {
 147: }
 148:  
 149: void tmp1Frame::OnClose(wxCloseEvent &event)
 150: {
 151:     Destroy();
 152: }
 153:  
 154: void tmp1Frame::OnQuit(wxCommandEvent &event)
 155: {
 156:     Destroy();
 157: }
 158:  
 159: void tmp1Frame::OnAbout(wxCommandEvent &event)
 160: {
 161:     wxString msg = wxbuildinfo(long_f);
 162:     wxMessageBox(msg, _("Welcome to..."));
 163: }
 164:  
 165: // set render_loop_on true, make OnIdle can draw text
 166: void tmp1Frame::OnStartLoop(wxCommandEvent& event)
 167: {
 168:     render_loop_on = true;
 169: }
 170:  
 171: // set render_loop_on true, make OnIdle can skip draw text
 172: void tmp1Frame::OnStopLoop(wxCommandEvent& event)
 173: {
 174:     render_loop_on = false;
 175: }
 176:  
 177: // paint depend on render_loop_on is true or off
 178: void tmp1Frame::OnIdle(wxIdleEvent& event)
 179: {
 180:     if (render_loop_on)
 181:     {
 182:         PaintNow();
 183:         event.RequestMore();
 184:     }
 185: }
 186:  
 187: void tmp1Frame::PaintNow()
 188: {
 189:     wxClientDC dc(this);
 190:     render(dc);
 191: }
 192:  
 193: // draw text on screen
 194: void tmp1Frame::render(wxDC& dc)
 195: {
 196:     static int y = 0;
 197:     static int y_speed = 2;
 198:  
 199:     y += y_speed;
 200:     if (y < 0) y_speed = 2;
 201:     if (y > 200) y_speed = -2;
 202:  
 203:     dc.SetBackground(*wxWHITE_BRUSH);
 204:     dc.Clear();
 205:     dc.DrawText(wxT("Testing"),40,y);
 206: }
 207:  

2. 时间处理方式

采用onTimer,具有较为固定的处理频率,当处理其他操作如打开菜单式,并不会中止;速度不像事件处理方式那么快,实现的速率与操作系统相关。

目前知道的wxTimer实现的方式有两种,1. 采用EVT_TIMER事件处理方式(该处理方法已经在文简易定时器设计中实现) 2. 创建一个wxTimer的子类,然后对wxTimer中的Notify函数进行重载。

下面采用第二种方式,进行实现。

tmp1Main.h

   1: /***************************************************************
   2:  * Name:      tmp1Main.h
   3:  * Purpose:   Defines Application Frame
   4:  * Author:    grass in moon 
   5:  * Created:   2012-07-06
   6:  * Copyright: grass in moon (http://www.cppblog.com/grass-and-moon/)
   7:  * License:
   8:  **************************************************************/
   9:  
  10: #ifndef TMP1MAIN_H
  11: #define TMP1MAIN_H
  12:  
  13: #ifndef WX_PRECOMP
  14: #include <wx/wx.h>
  15: #endif
  16:  
  17: #include "tmp1App.h"
  18:  
  19: class RenderTimer;         // make renderTimer.h not influence this file compling time
  20:  
  21: class tmp1Frame: public wxFrame
  22: {
  23: public:
  24:     tmp1Frame(wxFrame *frame, const wxString& title);
  25:     ~tmp1Frame();
  26:  
  27:     // for painting
  28:     void PaintNow();
  29:     void render(wxDC& dc);
  30:  
  31: private:
  32:     // derived from wxTimer
  33:     RenderTimer* timer;
  34:  
  35:     enum
  36:     {
  37:         idMenuQuit = 1000,
  38:         idMenuAbout,
  39:         idStartLoop,
  40:         idStopLoop
  41:     };
  42:  
  43:     void OnClose(wxCloseEvent& event);
  44:     void OnQuit(wxCommandEvent& event);
  45:     void OnAbout(wxCommandEvent& event);
  46:     void OnStartLoop(wxCommandEvent& event);
  47:     void OnStopLoop(wxCommandEvent& event);
  48:  
  49:     DECLARE_EVENT_TABLE()
  50: };
  51:  
  52: #endif // TMP1MAIN_H

tmp1Main.cpp

   1: /***************************************************************
   2:  * Name:      tmp1Main.cpp
   3:  * Purpose:   Code for Application Frame
   4:  * Author:    grass in moon 
   5:  * Created:   2012-07-06
   6:  * Copyright: grass in moon (http://www.cppblog.com/grass-and-moon/)
   7:  * License:
   8:  **************************************************************/
   9:  
  10: #ifdef WX_PRECOMP
  11: #include "wx_pch.h"
  12: #endif
  13:  
  14: #ifdef __BORLANDC__
  15: #pragma hdrstop
  16: #endif //__BORLANDC__
  17:  
  18: #include "tmp1Main.h"
  19: #include "renderTimer.h"
  20:  
  21: //helper functions
  22: enum wxbuildinfoformat
  23: {
  24:     short_f, long_f
  25: };
  26:  
  27: wxString wxbuildinfo(wxbuildinfoformat format)
  28: {
  29:     wxString wxbuild(wxVERSION_STRING);
  30:  
  31:     if (format == long_f )
  32:     {
  33: #if defined(__WXMSW__)
  34:         wxbuild << _T("-Windows");
  35: #elif defined(__WXMAC__)
  36:         wxbuild << _T("-Mac");
  37: #elif defined(__UNIX__)
  38:         wxbuild << _T("-Linux");
  39: #endif
  40:  
  41: #if wxUSE_UNICODE
  42:         wxbuild << _T("-Unicode build");
  43: #else
  44:         wxbuild << _T("-ANSI build");
  45: #endif // wxUSE_UNICODE
  46:     }
  47:  
  48:     return wxbuild;
  49: }
  50:  
  51: BEGIN_EVENT_TABLE(tmp1Frame, wxFrame)
  52:     EVT_CLOSE(tmp1Frame::OnClose)
  53:     EVT_MENU(idMenuQuit, tmp1Frame::OnQuit)
  54:     EVT_MENU(idMenuAbout, tmp1Frame::OnAbout)
  55:     EVT_MENU(idStartLoop, tmp1Frame::OnStartLoop)
  56:     EVT_MENU(idStopLoop, tmp1Frame::OnStopLoop)
  57: END_EVENT_TABLE()
  58:  
  59: tmp1Frame::tmp1Frame(wxFrame *frame, const wxString& title)
  60:     : wxFrame(frame, -1, title)
  61: {
  62: #if wxUSE_MENUS
  63:     // create a menu bar
  64:     wxMenuBar* mbar = new wxMenuBar();
  65:     wxMenu* fileMenu = new wxMenu(_T(""));
  66:     fileMenu->Append(idMenuQuit, _("&Quit\tAlt-F4"), _("Quit the application"));
  67:     fileMenu->Append(idStartLoop, _("St&artLoop"));       // for starting draw text
  68:     fileMenu->Append(idStopLoop, _("Sto&pLoop"));         // for stoping draw text
  69:     mbar->Append(fileMenu, _("&File"));
  70:  
  71:     wxMenu* helpMenu = new wxMenu(_T(""));
  72:     helpMenu->Append(idMenuAbout, _("&About\tF1"), _("Show info about this application"));
  73:     mbar->Append(helpMenu, _("&Help"));
  74:  
  75:     SetMenuBar(mbar);
  76: #endif // wxUSE_MENUS
  77:  
  78: #if wxUSE_STATUSBAR
  79:     // create a status bar with some information about the used wxWidgets version
  80:     CreateStatusBar(2);
  81:     SetStatusText(_("Hello Code::Blocks user!"),0);
  82:     SetStatusText(wxbuildinfo(short_f), 1);
  83: #endif // wxUSE_STATUSBAR
  84:  
  85:     timer = new RenderTimer(this);
  86: }
  87:  
  88:  
  89: tmp1Frame::~tmp1Frame()
  90: {
  91:     delete timer;
  92: }
  93:  
  94: void tmp1Frame::OnClose(wxCloseEvent &event)
  95: {
  96:     Destroy();
  97: }
  98:  
  99: void tmp1Frame::OnQuit(wxCommandEvent &event)
 100: {
 101:     Destroy();
 102: }
 103:  
 104: void tmp1Frame::OnAbout(wxCommandEvent &event)
 105: {
 106:     wxString msg = wxbuildinfo(long_f);
 107:     wxMessageBox(msg, _("Welcome to..."));
 108: }
 109:  
 110: // set render_loop_on true, make OnIdle can draw text
 111: void tmp1Frame::OnStartLoop(wxCommandEvent& event)
 112: {
 113:     timer->StartLoop();
 114: }
 115:  
 116: // set render_loop_on true, make OnIdle can skip draw text
 117: void tmp1Frame::OnStopLoop(wxCommandEvent& event)
 118: {
 119:     timer->StopLoop();
 120: }
 121:  
 122: void tmp1Frame::PaintNow()
 123: {
 124:     wxClientDC dc(this);
 125:     render(dc);
 126: }
 127:  
 128: // draw text on screen
 129: void tmp1Frame::render(wxDC& dc)
 130: {
 131:     static int y = 0;
 132:     static int y_speed = 2;
 133:  
 134:     y += y_speed;
 135:     if (y < 0) y_speed = 2;
 136:     if (y > 200) y_speed = -2;
 137:  
 138:     dc.SetBackground(*wxWHITE_BRUSH);
 139:     dc.Clear();
 140:     dc.DrawText(wxT("Testing"),40,y);
 141: }

renderTimer.h

   1: /***************************************************************
   2:  * Name:      renderTimer.h
   3:  * Purpose:   used for onTimer
   4:  * Author:    grass in moon 
   5:  * Created:   2012-07-06
   6:  * Copyright: grass in moon (http://www.cppblog.com/grass-and-moon/)
   7:  * License:
   8:  **************************************************************/
   9:  
  10: #ifndef RENDERTIMER_H_INCLUDED
  11: #define RENDERTIMER_H_INCLUDED
  12:  
  13: class tmp1Frame;
  14:  
  15: class RenderTimer : public wxTimer
  16: {
  17:     tmp1Frame* tmpFrame;
  18: public:
  19:     RenderTimer(tmp1Frame* tmpFrame);
  20:     void Notify();
  21:     void StartLoop();
  22:     void StopLoop();
  23: };
  24:  
  25: #endif // RENDERTIMER_H_INCLUDED

renderTimer.cpp

   1: /***************************************************************
   2:  * Name:      renderTimer.cpp
   3:  * Purpose:   used for onTimer
   4:  * Author:    grass in moon 
   5:  * Created:   2012-07-06
   6:  * Copyright: grass in moon (http://www.cppblog.com/grass-and-moon/)
   7:  * License:
   8:  **************************************************************/
   9: #include "tmp1Main.h"
  10: #include "renderTimer.h"
  11:  
  12: RenderTimer::RenderTimer(tmp1Frame* tmpFrame)
  13: {
  14:     this->tmpFrame = tmpFrame;
  15: }
  16:  
  17: // perform the draw text action
  18: void RenderTimer::Notify()
  19: {
  20:     tmpFrame->PaintNow();
  21: }
  22:  
  23: // set the interval time is 10 ms
  24: void RenderTimer::StartLoop()
  25: {
  26:     wxTimer::Start(10);
  27: }
  28:  
  29: void RenderTimer::StopLoop()
  30: {
  31:     wxTimer::Stop();
  32: }

posted on 2012-07-06 11:17 钟谢伟 阅读(1516) 评论(0)  编辑 收藏 引用


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理


<2012年7月>
24252627282930
1234567
891011121314
15161718192021
22232425262728
2930311234

导航

统计

常用链接

留言簿(1)

随笔档案

IT网站

My Friends

搜索

最新评论

阅读排行榜

评论排行榜