<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                # wxWidgets 中的事件 > 原文: [http://zetcode.com/gui/wxwidgets/events/](http://zetcode.com/gui/wxwidgets/events/) 事件是每個 GUI 應用不可或缺的一部分。 所有 GUI 應用都是事件驅動的。 應用會對在其生命周期內生成的不同事件類型做出反應。 事件主要由應用的用戶生成。 但是它們也可以通過其他方式生成,例如互聯網連接,窗口管理器或計時器。 當應用啟動時,將創建一個主循環。 該應用位于主循環中,并等待事件生成。 當我們退出應用時,主循環退出。 ## 定義 事件是來自底層框架(通常是 GUI 工具箱)的應用級信息。事件循環是一種程序結構,用于等待并調度器中的事件或消息。 事件循環反復查找事件以對其進行處理。調度器是將事件映射到事件處理器的過程。 事件處理器是對事件做出反應的方法。 事件對象是與事件關聯的對象。 通常是一個窗口。事件類型是已生成的唯一事件。 ## 一個簡單的事件示例 在 wxWidgets 中處理事件的傳統方法是使用靜態事件表。這受 Microsoft 基礎類(MFC)的影響。 一種更靈活,更現代的方法是使用`Connect()`方法。 我們在整個 wxWidgets 教程中都使用它。 ## 事件表 在下一個示例中,我們顯示一個使用事件表的示例。 `button.h` ```cpp #include <wx/wx.h> class MyButton : public wxFrame { public: MyButton(const wxString& title); void OnQuit(wxCommandEvent& event); private: DECLARE_EVENT_TABLE() }; ``` `button.cpp` ```cpp #include "button.h" MyButton::MyButton(const wxString& title) : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(270, 150)) { wxPanel *panel = new wxPanel(this, wxID_ANY); wxButton *button = new wxButton(panel, wxID_EXIT, wxT("Quit"), wxPoint(20, 20)); Centre(); } void MyButton::OnQuit(wxCommandEvent& WXUNUSED(event)) { Close(true); } BEGIN_EVENT_TABLE(MyButton, wxFrame) EVT_BUTTON(wxID_EXIT, MyButton::OnQuit) END_EVENT_TABLE() ``` `main.h` ```cpp #include <wx/wx.h> class MyApp : public wxApp { public: virtual bool OnInit(); }; ``` `main.cpp` ```cpp #include "main.h" #include "button.h" IMPLEMENT_APP(MyApp) bool MyApp::OnInit() { MyButton *button = new MyButton(wxT("Button")); button->Show(true); return true; } ``` 在我們的示例中,我們創建一個簡單的按鈕。 通過單擊按鈕,我們關閉應用。 ```cpp private: DECLARE_EVENT_TABLE() ``` 在頭文件中,我們使用`DECLARE_EVENT_TABLE()`宏聲明一個事件表。 ```cpp BEGIN_EVENT_TABLE(MyButton, wxFrame) EVT_BUTTON(wxID_EXIT, MyButton::OnQuit) END_EVENT_TABLE() ``` 我們通過將每個事件映射到適當的成員函數來實現事件表。 ## 使用`Connect()`的示例 我們將討論移動事件。 移動事件保存有關移動更改事件的信息。 當我們將窗口移到新位置時,將生成一個移動事件。 表示移動事件的類為`wxMoveEvent`。 `wxEVT_MOVE`是事件類型。 `move.h` ```cpp #include <wx/wx.h> class Move : public wxFrame { public: Move(const wxString& title); void OnMove(wxMoveEvent & event); wxStaticText *st1; wxStaticText *st2; }; ``` `move.cpp` ```cpp #include "move.h" Move::Move(const wxString& title) : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(250, 130)) { wxPanel *panel = new wxPanel(this, -1); st1 = new wxStaticText(panel, -1, wxT(""), wxPoint(10, 10)); st2 = new wxStaticText(panel, -1, wxT(""), wxPoint(10, 30)); Connect(wxEVT_MOVE, wxMoveEventHandler(Move::OnMove)); Centre(); } void Move::OnMove(wxMoveEvent& event) { wxPoint size = event.GetPosition(); st1->SetLabel(wxString::Format(wxT("x: %d"), size.x )); st2->SetLabel(wxString::Format(wxT("y: %d"), size.y )); } ``` `main.h` ```cpp #include <wx/wx.h> class MyApp : public wxApp { public: virtual bool OnInit(); }; ``` `main.cpp` ```cpp #include "main.h" #include "move.h" IMPLEMENT_APP(MyApp) bool MyApp::OnInit() { Move *move = new Move(wxT("Move event")); move->Show(true); return true; } ``` 該示例顯示窗口的當前位置。 ```cpp Connect(wxEVT_MOVE, wxMoveEventHandler(Move::OnMove)); ``` 在這里,我們將`wxEVT_MOVE`事件類型與`OnMove()`方法連接在一起。 ```cpp wxPoint size = event.GetPosition(); ``` `OnMove()`方法中的事件參數是特定于特定事件的對象。 在我們的例子中,它是`wxMoveEvent`類的實例。 該對象保存有關事件的信息。 我們可以通過調用事件的`GetPosition()`方法找出當前位置。 ![Move event](https://img.kancloud.cn/a3/2e/a32e3b85c1cb59d030ae2598a507f1ff_290x189.jpg) 圖:移動事件 ## 事件傳播 事件有兩種類型:基本事件和命令事件。 它們的傳播方式不同。 事件傳播是事件從子小部件傳播到父小部件和祖父小部件等的事件。基本事件不傳播。 命令事件確實傳播。 例如,`wxCloseEvent`是一個基本事件。 此事件傳播到父窗口小部件沒有任何意義。 默認情況下,在事件處理器中捕獲的事件停止傳播。 要繼續傳播,我們必須調用`Skip()`方法。 `propagate.h` ```cpp #include <wx/wx.h> class Propagate : public wxFrame { public: Propagate(const wxString& title); void OnClick(wxCommandEvent& event); }; class MyPanel : public wxPanel { public: MyPanel(wxFrame *frame, int id); void OnClick(wxCommandEvent& event); }; class MyButton : wxButton { public: MyButton(MyPanel *panel, int id, const wxString &label); void OnClick(wxCommandEvent& event); }; ``` `propagate.cpp` ```cpp #include <iostream> #include "propagate.h" const int ID_BUTTON = 1; Propagate::Propagate(const wxString& title) : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(250, 130)) { MyPanel *panel = new MyPanel(this, -1); new MyButton(panel, ID_BUTTON, wxT("Ok")); Connect(ID_BUTTON, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(Propagate::OnClick)); Centre(); } void Propagate::OnClick(wxCommandEvent& event) { std::cout << "event reached frame class" << std::endl; event.Skip(); } MyPanel::MyPanel(wxFrame *frame, int id) : wxPanel(frame, id) { Connect(ID_BUTTON, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MyPanel::OnClick)); } void MyPanel::OnClick(wxCommandEvent& event) { std::cout << "event reached panel class" << std::endl; event.Skip(); } MyButton::MyButton(MyPanel *mypanel, int id, const wxString& label) : wxButton(mypanel, id, label, wxPoint(15, 15)) { Connect(ID_BUTTON, wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler(MyButton::OnClick)); } void MyButton::OnClick(wxCommandEvent& event) { std::cout << "event reached button class" << std::endl; event.Skip(); } ``` `main.h` ```cpp #include <wx/wx.h> class MyApp : public wxApp { public: virtual bool OnInit(); }; ``` `main.cpp` ```cpp #include "main.h" #include "propagate.h" IMPLEMENT_APP(MyApp) bool MyApp::OnInit() { Propagate *prop = new Propagate(wxT("Propagate")); prop->Show(true); return true; } ``` 在我們的示例中,面板上有一個按鈕。 面板放置在框架小部件中。 我們為所有小部件定義一個處理器。 ```cpp event reached button class event reached panel class event reached frame class ``` 當我們點擊按鈕時,我們得到了這個。 事件從按鈕傳播到面板和框架。 嘗試省略一些`Skip()`方法,看看會發生什么。 ## 取消事件 有時我們需要停止處理事件。 為此,我們稱方法`Veto()`。 `veto.h` ```cpp #include <wx/wx.h> class Veto : public wxFrame { public: Veto(const wxString& title); void OnClose(wxCloseEvent& event); }; ``` `veto.cpp` ```cpp #include "veto.h" Veto::Veto(const wxString& title) : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(250, 130)) { Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(Veto::OnClose)); Centre(); } void Veto::OnClose(wxCloseEvent& event) { wxMessageDialog *dial = new wxMessageDialog(NULL, wxT("Are you sure to quit?"), wxT("Question"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION); int ret = dial->ShowModal(); dial->Destroy(); if (ret == wxID_YES) { Destroy(); } else { event.Veto(); } } ``` `main.h` ```cpp #include <wx/wx.h> class MyApp : public wxApp { public: virtual bool OnInit(); }; ``` `main.cpp` ```cpp #include "main.h" #include "veto.h" IMPLEMENT_APP(MyApp) bool MyApp::OnInit() { Veto *veto = new Veto(wxT("Veto")); veto->Show(true); return true; } ``` 在我們的示例中,我們處理`wxCloseEvent`。 當我們單擊標題欄上的 X 按鈕,按 `Alt + F4` 或從系統菜單中選擇關閉時,將稱為此事件。 在許多應用中,如果要進行一些更改,我們希望防止意外關閉窗口。 為此,我們必須連接`wxEVT_CLOSE_WINDOW`事件類型。 ```cpp wxMessageDialog *dial = new wxMessageDialog(NULL, wxT("Are you sure to quit?"), wxT("Question"), wxYES_NO | wxNO_DEFAULT | wxICON_QUESTION); ``` 在關閉事件期間,我們顯示一個消息對話框。 ```cpp if (ret == wxID_YES) { Destroy(); } else { event.Veto(); } ``` 根據返回值,我們銷毀窗口或否決事件。 注意,要關閉窗口,我們必須調用`Destroy()`方法。 通過調用`Close()`方法,我們將陷入無盡的循環。 ## 窗口標識符 窗口標識符是在事件系統中唯一確定窗口標識的整數。 有三種創建窗口 ID 的方法: * 讓系統自動創建一個 ID。 * 使用標準標識符。 * 創建我們自己的 ID。 每個小部件都有一個 id 參數。 這是事件系統中的唯一編號。 如果我們使用多個小部件,則必須在它們之間進行區分。 ```cpp wxButton(parent, -1) wxButton(parent, wxID_ANY) ``` 如果為 ID 參數提供 -1 或`wxID_ANY`,則讓 wxWidgets 自動為我們創建一個 ID。 自動創建的 ID 始終為負,而用戶指定的 ID 必須始終為正。 當我們不需要更改窗口小部件狀態時,通常使用此選項。 例如,靜態文本在應用的生命周期內將永遠不會更改。 如果需要,我們仍然可以獲取 ID。 有一種方法`GetId()`,它將為我們確定 ID。 應盡可能使用標準標識符。 標識符可以在某些平臺上提供一些標準的圖形或行為。 `ident.h` ```cpp #include <wx/wx.h> class Ident : public wxFrame { public: Ident(const wxString& title); }; ``` `ident.cpp` ```cpp #include "ident.h" Ident::Ident(const wxString& title) : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(200, 150)) { wxPanel *panel = new wxPanel(this, -1); wxGridSizer *grid = new wxGridSizer(2, 3); grid->Add(new wxButton(panel, wxID_CANCEL), 0, wxTOP | wxLEFT, 9); grid->Add(new wxButton(panel, wxID_DELETE), 0, wxTOP, 9); grid->Add(new wxButton(panel, wxID_SAVE), 0, wxLEFT, 9); grid->Add(new wxButton(panel, wxID_EXIT)); grid->Add(new wxButton(panel, wxID_STOP), 0, wxLEFT, 9); grid->Add(new wxButton(panel, wxID_NEW)); panel->SetSizer(grid); Centre(); } ``` `main.h` ```cpp #include <wx/wx.h> class MyApp : public wxApp { public: virtual bool OnInit(); }; ``` `main.cpp` ```cpp #include "main.h" #include "ident.h" IMPLEMENT_APP(MyApp) bool MyApp::OnInit() { Ident *ident = new Ident(wxT("Identifiers")); ident->Show(true); return true; } ``` 在我們的示例中,我們在按鈕上使用標準標識符。 在 Linux 上,按鈕帶有小圖標。 ![Identifiers](https://img.kancloud.cn/b2/04/b20488ae538e25b7e8f06acc1edc01de_240x209.jpg) 圖:標識符 在本章中,我們討論了 wxWidgets 中的事件。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看