wxWidgets動態事件表愛好者備查手冊

 

wxWidgets動態事件表愛好者備查手冊

作者:皿(http://blog.csdn.net/utensil/

 

      使用動態事件映射方法的原因,可能是你想在程序運行的不同時刻使用不同的映射關係,或者因爲你使用的那種語言(例如python)不支持靜態映射,或者僅僅是因爲你更喜歡動態映射。因爲動態映射的方法可以使你更精確的控制事件表的細節,你甚至可以單獨的將事件表中的某一個條目在運行期打開或者關閉,而前面說的PushEventHandler和PopEventHandler的方法只能針對整個事件表進行處理。除此以外,動態事件處理還允許你在不同的類之間共享事件函數。

——《WxWidgets跨平臺GUI開發》

導言

      在wxWidgets中,相對於靜態事件表那種僵死並且不知其所以然的方法,我更喜歡動態事件表,親自Connect,還可以隨時Disconnect。

      但是,在寫動態事件表時,會遇到一個問題,wxWidgets的官方文檔中的事件處理部份,對於靜態事件表所需的各種事件類型的宏敘述詳盡,卻對動態事件表所需的事件類型語焉不詳,這給我們的使用帶來了麻煩。需要的知識一方面零星分佈於wx文檔中,另一方面被冗長的代碼掩映在<wx/event.h>中。此文的目的,就是爲動態事件表的愛好者提供一個方便查詢的手冊,希望能給大家幫助。

      大部份寫GUI常用的wx類(包括窗口、對話框、控件)都繼承於三個類:wxWindowwx、wxEvtHandler、wxObject。因此,大多數情況下,這三個類的成員函數是我們可以順手牽過來用的。動態事件表的使用中,最爲重要的函數Connect和Disconnect就是wxEvtHandler的成員函數,我們可以牽過來給我們手頭這個要處理事件的wx類用。

 

      先看看官方文檔裏對Connect函數的介紹(我對其進行了翻譯、精簡,有時,爲了解釋的明晰,作一些補充說明):

 

#TRANSLATE BEGIN 


  •  

   wxEvtHandler::Connect   

Connect函數被重載了三次,各有各的用途。

第一個版本:範圍捕殺 ( [id, lastid] 且 eventType)

void Connect(int id, int lastId, wxEventType eventType, wxObjectEventFunction function, wxObject* userData = NULL, wxEvtHandler* eventSink = NULL)

第二個版本:精確狙擊(id 且 eventType)

void Connect(int id, wxEventType eventType, wxObjectEventFunction function, wxObject* userData = NULL, wxEvtHandler* eventSink = NULL)

第三個版本:分門別類 (僅 eventType)

void Connect(wxEventType eventType, wxObjectEventFunction function, wxObject* userData = NULL, wxEvtHandler* eventSink = NULL)

      該函數動態地將所給事件處理函數 與 EventHandler、ID 甚至事件類型聯繫起來。這是靜態事件表的一種替代選擇。

      按:EventHandler直譯爲事件處理器,或可譯爲“事件手柄”(生動地模仿句柄)?後文使用“事件手柄”。

參數意義:

id

    •  
    •  
    •  
    •  
    •  

你要和事件處理函數聯繫起來的ID(可以是窗口ID、菜單ID、控件ID)。對於沒有這個參數的重載版本,id被默認設爲 wxID_ANY。

當和lastid連用時,表達的是一個ID範圍,即大小介於id和last id之間的所有ID,都會被Connect函數與事件處理函數聯繫起來。

按:實在沒必要連“ID”都譯成“標識符”……其實看技術文檔時,我最頭痛的是一堆漢字堆在那裏,包括看數學書時……

lastId

    • 參見
id中的介紹。

eventType

    • 你要和事件處理函數聯繫起來的Event Type。
按:Event Type直譯爲“事件類型”並不恰當,因爲事件類型是指形如wxMouseEvent這樣的東西,而這裏所指,是形如wxEVT_MOTION這樣的東西。 準確地說,應該稱之爲“事件標識符”或“事件ID”。下文使用“事件ID”。 一個事件類型裏,會有若干事件ID,比wxMouseEvent裏除了wxEVT_MOTION,還有wxEVT_LEFT_DOWN等等等事件ID。 因此可以把事件ID作爲對事件類型的一個細分。

function

    • 事件處理函數。注意這個函數應當被顯式轉換爲正確的類型。 對於類型爲wxFooEvent的事件,轉換使用宏
wxFooEventHandler。

userData

    •  
    • 你要和事件表項聯繫起來的數據。(暫時我還不知道這個有什麼用)

eventSink

    • 告訴Connect函數,你要調用的事件處理函數是誰的成員函數。 如果該參數爲 NULL, 那麼Connect函數將使用
this指針 。 按:正是這個參數允許了我們在不同類中共享事件處理函數。

例子:

  frame->Connect( wxID_EXIT,
                  wxEVT_COMMAND_MENU_SELECTED,
                  wxCommandEventHandler(MyFrame::OnQuit) );
   對例子的解釋:
     wxID_EXIT是之前賦給了某一個菜單項的ID。
    當該菜單被選擇時,會產生一個ID爲wxEVT_COMMAND_MENU_SELECTED的事件。
    因此MyFrame::OnQuit在被顯式轉換爲wxCommandEventHandler型的“事件手柄”之後,被Connect拉過來處理該事件。
 
    

      就不再翻譯Disconnect函數的文檔了,因爲除了函數名不同,它的所有參數和Connect是一模一樣的。它的用途就是斷開Connect所建立起來的聯繫。

      實踐中寫事件處理的時候,通常使用的是Connect的後兩種重載版本。參數userData和eventSink的使用是比較少的,而且也有默認值,一般不去理它就可以了。

      參數id是你賦給產生了這個事件的窗口、菜單或控件的,你自己心裏是清楚的。問題頂多是,你需要使用系統默認的那些ID(比如上面例子裏的wxID_EXIT),而你不知道哪個還哪個。那些ID的列表在官方文檔裏是有的,不過爲了本文作爲手冊的完整性,將在本文最後給出。

      有時是不需要id的,比如鼠標移動的事件:

      frame->Connect(wxEVT_MOTION,wxMouseEventHandler(MyFrame::OnMouseMove));

      直接把事件ID與事件手柄聯繫起來。       參數function的問題大一些,就是這個顯式強制類型轉換的這個Handler,具體叫wx什麼EventHandler呢?這個問題也好解決,因爲官方文檔裏的Classes By Category裏的Event小節已經給出了形如wxFooEvent這樣的事件類型的列表,只需要在相應的事件類型後面加上Handler就可以了。同樣爲了本文作爲手冊的完整性,將在本文後面給出全部Handler的列表。

      最大的問題出在參數eventType上。形如wxEVT_MOTION、wxEVT_COMMAND_MENU_SELECTED這樣的事件ID的名字,我們從何得知?這些奇形怪狀的名字,縱然我們英語很強,也未必能造出和wxWidgets定義的一模一樣的名字啊。比如寫慣MFC的同好們很容易將鼠標移動事件ID寫爲wxMOUSEMOVE或wxMOUSE_MOVE,可這卻是錯的。最糟糕的是,文檔中沒有提供這些名字的列表!

      有些同好可能發現了,對大部份事件類型的靜態事件表的宏的說明中,包含了這方面的重要信息,例如wxPaintEvent裏:

      EVT_PAINT(func)    Process a wxEVT_PAINT event.

      左邊是靜態事件表需要的,右邊是動態事件表需要的。左手靜態,右手動態,好瀟灑啊!然而,倘若你要處理窗口關閉事件(假設該事件的產生不是通過菜單選擇,而是點窗口右上角的紅叉叉),你跑到wxCloseEvent那裏一看:

      EVT_CLOSE(func)       Process a close event, supplying the member function. This event applies to wxFrame and wxDialog classes.

      你暈了……爲什麼文檔編寫者連這都不肯告訴你?!於是你嘗試着用wxEVT_CLOSE,編譯器告訴你不對。已經習慣了沒事翻翻頭文件的你就跑到<wx/event.h>裏去找了,一搜索就出來了。 原來是wxEVT_CLOSE_WINDOW,這可真是情理之中意料之外啊,反正我當時是接近吐血了……

      所幸這個情況並沒有出現在大多數基本的事件裏,但實際中總會需要處理那些不那麼基本的事件的,每次都在這個細節上卡這麼久的殼太不划算了。所以我把事件ID列表從<wx/event.h>中抽出來並加以翻譯,大家放在手邊備查吧。這是本文的主要寫作目的。

      說了一堆稀哩嘩啦的廢話,下面進入手冊正文。

事件ID列表

 

·命令事件

wxEVT_COMMAND_BUTTON_CLICKED, 1 wxEVT_COMMAND_CHECKBOX_CLICKED, 2 wxEVT_COMMAND_CHOICE_SELECTED, 3 wxEVT_COMMAND_LISTBOX_SELECTED, 4 wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, 5 wxEVT_COMMAND_CHECKLISTBOX_TOGGLED, 6

以下這一段事件ID由於版本更新,已經移到了<wx/textctrl.h>中進行定義。

#if WXWIN_COMPATIBILITY_EVENT_TYPES wxEVT_COMMAND_TEXT_UPDATED, 7 wxEVT_COMMAND_TEXT_ENTER, 8 wxEVT_COMMAND_TEXT_URL, 13 wxEVT_COMMAND_TEXT_MAXLEN, 14 #endif // WXWIN_COMPATIBILITY_EVENT_TYPES

wxEVT_COMMAND_MENU_SELECTED, 9 wxEVT_COMMAND_SLIDER_UPDATED, 10 wxEVT_COMMAND_RADIOBOX_SELECTED, 11 wxEVT_COMMAND_RADIOBUTTON_SELECTED, 12

wxEVT_COMMAND_SCROLLBAR_UPDATED 現在已廢棄不用,轉而使用wxEVT_SCROLL。

wxEVT_COMMAND_SCROLLBAR_UPDATED, 13 wxEVT_COMMAND_VLBOX_SELECTED, 14 wxEVT_COMMAND_COMBOBOX_SELECTED, 15 wxEVT_COMMAND_TOOL_RCLICKED, 16 wxEVT_COMMAND_TOOL_ENTER, 17 wxEVT_COMMAND_SPINCTRL_UPDATED, 18

 

以下兩個事件也被廢棄了// Sockets and timers send events, too

DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_BASE, wxEVT_SOCKET, 50) wxEVT_TIMER , 80

 

·鼠標事件

wxEVT_LEFT_DOWN, 100 wxEVT_LEFT_UP, 101 wxEVT_MIDDLE_DOWN, 102 wxEVT_MIDDLE_UP, 103 wxEVT_RIGHT_DOWN, 104 wxEVT_RIGHT_UP, 105 wxEVT_MOTION, 106 wxEVT_ENTER_WINDOW, 107 wxEVT_LEAVE_WINDOW, 108 wxEVT_LEFT_DCLICK, 109 wxEVT_MIDDLE_DCLICK, 110 wxEVT_RIGHT_DCLICK, 111 wxEVT_SET_FOCUS, 112 wxEVT_KILL_FOCUS, 113 wxEVT_CHILD_FOCUS, 114 wxEVT_MOUSEWHEEL, 115

 

·非客戶區(Non-client)鼠標事件

wxEVT_NC_LEFT_DOWN, 200 wxEVT_NC_LEFT_UP, 201 wxEVT_NC_MIDDLE_DOWN, 202 wxEVT_NC_MIDDLE_UP, 203 wxEVT_NC_RIGHT_DOWN, 204 wxEVT_NC_RIGHT_UP, 205 wxEVT_NC_MOTION, 206 wxEVT_NC_ENTER_WINDOW, 207 wxEVT_NC_LEAVE_WINDOW, 208 wxEVT_NC_LEFT_DCLICK, 209 wxEVT_NC_MIDDLE_DCLICK, 210 wxEVT_NC_RIGHT_DCLICK, 211

 

·字符輸入事件

wxEVT_CHAR, 212 wxEVT_CHAR_HOOK, 213 wxEVT_NAVIGATION_KEY, 214 wxEVT_KEY_DOWN, 215 wxEVT_KEY_UP, 216 #if wxUSE_HOTKEY wxEVT_HOTKEY, 217 #endif

 

·設置焦點(Cursor)事件

wxEVT_SET_CURSOR, 230

 

· 來自wxScrollBar控件和wxSlider控件的滾動事件

wxEVT_SCROLL_TOP, 300 wxEVT_SCROLL_BOTTOM, 301 wxEVT_SCROLL_LINEUP, 302 wxEVT_SCROLL_LINEDOWN, 303 wxEVT_SCROLL_PAGEUP, 304 wxEVT_SCROLL_PAGEDOWN, 305 wxEVT_SCROLL_THUMBTRACK, 306 wxEVT_SCROLL_THUMBRELEASE, 307 wxEVT_SCROLL_CHANGED, 308

 

·來自wxWindow的滾動事件

wxEVT_SCROLLWIN_TOP, 320 wxEVT_SCROLLWIN_BOTTOM, 321 wxEVT_SCROLLWIN_LINEUP, 322 wxEVT_SCROLLWIN_LINEDOWN, 323 wxEVT_SCROLLWIN_PAGEUP, 324 wxEVT_SCROLLWIN_PAGEDOWN, 325 wxEVT_SCROLLWIN_THUMBTRACK, 326 wxEVT_SCROLLWIN_THUMBRELEASE, 327

 

·系統事件

wxEVT_SIZE, 400 wxEVT_MOVE, 401 wxEVT_CLOSE_WINDOW, 402 wxEVT_END_SESSION, 403 wxEVT_QUERY_END_SESSION, 404 wxEVT_ACTIVATE_APP, 405 406..408 被用於關於電源的事件上,這裏沒有列出。如果想查看這些事件,可去看<wx/power.h >。 wxEVT_ACTIVATE, 409 wxEVT_CREATE, 410 wxEVT_DESTROY, 411 wxEVT_SHOW, 412 wxEVT_ICONIZE, 413 wxEVT_MAXIMIZE, 414 wxEVT_MOUSE_CAPTURE_CHANGED, 415 wxEVT_MOUSE_CAPTURE_LOST, 416 wxEVT_PAINT, 417 wxEVT_ERASE_BACKGROUND, 418 wxEVT_NC_PAINT, 419 wxEVT_PAINT_ICON, 420 wxEVT_MENU_OPEN, 421 wxEVT_MENU_CLOSE, 422 wxEVT_MENU_HIGHLIGHT, 423 wxEVT_CONTEXT_MENU, 424 wxEVT_SYS_COLOUR_CHANGED, 425 wxEVT_DISPLAY_CHANGED, 426 wxEVT_SETTING_CHANGED, 427 wxEVT_QUERY_NEW_PALETTE, 428 wxEVT_PALETTE_CHANGED, 429 wxEVT_JOY_BUTTON_DOWN, 430 wxEVT_JOY_BUTTON_UP, 431 wxEVT_JOY_MOVE, 432 wxEVT_JOY_ZMOVE, 433 wxEVT_DROP_FILES, 434 wxEVT_DRAW_ITEM, 435 wxEVT_MEASURE_ITEM, 436 wxEVT_COMPARE_ITEM, 437 wxEVT_INIT_DIALOG, 438 wxEVT_IDLE, 439 wxEVT_UPDATE_UI, 440 wxEVT_SIZING, 441 wxEVT_MOVING, 442 wxEVT_HIBERNATE, 443

 

·剪貼板事件

wxEVT_COMMAND_TEXT_COPY, 444 wxEVT_COMMAND_TEXT_CUT, 445 wxEVT_COMMAND_TEXT_PASTE, 446

 

·通用命令事件(注意,一個Click事件是比button down/up優先級更高的。

wxEVT_COMMAND_LEFT_CLICK, 500 wxEVT_COMMAND_LEFT_DCLICK, 501 wxEVT_COMMAND_RIGHT_CLICK, 502 wxEVT_COMMAND_RIGHT_DCLICK, 503 wxEVT_COMMAND_SET_FOCUS, 504 wxEVT_COMMAND_KILL_FOCUS, 505 wxEVT_COMMAND_ENTER, 506

 

·幫助事件

wxEVT_HELP, 1050 wxEVT_DETAILED_HELP, 1051

 

以下兩個事件是等價的

wxEVT_COMMAND_TOOL_CLICKED        wxEVT_COMMAND_MENU_SELECTED

 

事件手柄列表

wxCommandEventHandler

wxScrollEventHandler

wxScrollWinEventHandler

wxSizeEventHandler

wxMoveEventHandler

wxPaintEventHandler

wxNcPaintEventHandler

wxEraseEventHandler

wxMouseEventHandler

wxCharEventHandler

wxKeyEventHandler wxCharEventHandler

wxFocusEventHandler

wxChildFocusEventHandler

wxActivateEventHandler

wxMenuEventHandler

wxJoystickEventHandler

wxDropFilesEventHandler

wxInitDialogEventHandler

wxSysColourChangedEventHandler

wxDisplayChangedEventHandler

wxUpdateUIEventHandler

wxIdleEventHandler

wxCloseEventHandler

wxShowEventHandler

wxIconizeEventHandler

wxMaximizeEventHandler

wxNavigationKeyEventHandler

wxPaletteChangedEventHandler

wxQueryNewPaletteEventHandler

wxWindowCreateEventHandler

wxWindowDestroyEventHandler

wxSetCursorEventHandler

wxNotifyEventHandler

wxHelpEventHandler

wxContextMenuEventHandler

wxMouseCaptureChangedEventHandler

wxMouseCaptureLostEventHandler

wxClipboardTextEventHandler

 

wxWidgets定義的標識符列表(摘自《WxWidgets跨平臺GUI開發》)

      窗口標識符是在事件系統中用來唯一確定窗口的整數。事實上,在整個應用程序的範圍內,窗口標識符不必一定是唯一的,而只要在某個固定的上下文(比如說,在一個frame窗口和它的所有子窗口)內是唯一的就可以了。舉例來說:你可以在無數個對話框中使用wxID_OK這個標識符,只要在某個對話框內不要重複使用就可以了。

      wxWidgets自動創建的標識符是總是一個負數,所以永遠不會和用戶定義的窗口標識符重複,用戶定義的窗口標識符只能是正整數。

 

標識符名稱 描述
wxID_ANY 讓wxWidgets自動產生一個標識符
wxID_LOWEST 最小的系統標識符值 (4999)
wxID_HIGHEST 最大的系統標識符值 (5999)
wxID_OPEN 打開文件
wxID_CLOSE 關閉窗口
wxID_NEW 新建窗口文件或者文檔
wxID_SAVE 保存文件
wxID_SAVEAS 文件另存爲(應該彈出文件位置對話框)
wxID_REVERT 恢復文件在磁盤上的狀態
wxID_EXIT 退出應用程序
wxID_UNDO 撤消最近一次操作
wxID_REDO 重複最近一次操作
wxID_HELP 幫助 (例如對話框上的幫助按鈕可以用這個標識符)
wxID_PRINT 打印
wxID_PRINT_SETUP 打印設置
wxID_PREVIEW 打印預覽
wxID_ABOUT 顯示一個用來描述整個程序的對話框
wxID_HELP_CONTENTS 顯示上下文幫助
wxID_HELP_COMMANDS 顯示應用程序命令
wxID_HELP_PROCEDURES 顯示應用程序過程
wxID_HELP_CONTEXT 未使用
wxID_CUT 剪切
wxID_COPY 複製到剪貼板
wxID_PASTE 粘貼
wxID_CLEAR 清除
wxID_FIND 查找
wxID_DUPLICATE 複製
wxID_SELECTALL 全選
wxID_DELETE 刪除
wxID_REPLACE 覆蓋
wxID_REPLACE_ALL 全部覆蓋
wxID_PROPERTIES 查看屬性
wxID_VIEW_DETAILS 列表框中的按照詳細信息方式顯示
wxID_VIEW_LARGEICONS 列表框按照大圖標的方式顯示
wxID_VIEW_SMALLICONS 列表框中按照小圖標的方式顯示
wxID_VIEW_LIST 列表框中按照列表的的方式顯示
wxID_VIEW_SORTDATE 按照日期排序
wxID_VIEW_SORTNAME 按照名稱排序
wxID_VIEW_SORTSIZE 按照大小排序
wxID_VIEW_SORTTYPE 按照類型排序
wxID_FILE1 to wxID_FILE9 顯示最近使用的文件
wxID_OK 確定
wxID_CANCEL 取消
wxID_APPLY 應用變更
wxID_YES YES
wxID_NO No
wxID_STATIC 靜態文本或者靜態圖片可以用這個標識符
wxID_FORWARD 向前
wxID_BACKWARD 向後
wxID_DEFAULT 恢復默認設置
wxID_MORE 顯示更多選項
wxID_SETUP 顯示一個設置對話框
wxID_RESET 重置所有選項
wxID_CONTEXT_HELP 顯示上下文幫助
wxID_YESTOALL 全部選是
wxID_NOTOALL 全部選否
wxID_ABORT 中止當前操作
wxID_RETRY 重試
wxID_IGNORE 忽略錯誤
wxID_UP 向上
wxID_DOWN 向下
wxID_HOME 首頁
wxID_REFRESH 刷新
wxID_STOP 停止正在進行的操作
wxID_INDEX 顯示一個索引
wxID_BOLD 加粗顯示
wxID_ITALIC 斜體顯示
wxID_JUSTIFY_CENTER 居中
wxID_JUSTIFY_FILL 格式
wxID_JUSTIFY_RIGHT 右對齊
wxID_JUSTIFY_LEFT 左對齊
wxID_UNDERLINE 下劃線
wxID_INDENT 縮進
wxID_UNINDENT 反縮進
wxID_ZOOM_100 放大到100%
wxID_ZOOM_FIT 縮放到整頁
wxID_ZOOM_IN 放大
wxID_ZOOM_OUT 縮小
wxID_UNDELETE 反刪除
wxID_REVERT_TO_SAVED 恢復到上次保存的狀態

 

      爲了避免你自己定義的標識符和這些預定義的標識符重複,你可以使用大於wxID_HIGHEST的標識符或者小於wxID_LOWEST的標識符。

發佈了37 篇原創文章 · 獲贊 2 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章