程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> wxWidget實現連續繪圖並能夠控制繪圖的開始與結束

wxWidget實現連續繪圖並能夠控制繪圖的開始與結束

編輯:C++入門知識

在用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: }
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved