美文网首页wxWidgets
wxWidget之HelloWorld

wxWidget之HelloWorld

作者: jdzhangxin | 来源:发表于2018-03-31 10:20 被阅读288次

    参考wxWidgets官方Hello World in wxWidgets编写一个简单的wxWidgets入门。

    从小的成功积累到大的成功

    编译&执行环境

    OS CPU IDE
    Win10 x64 VS2015+clang+VSCode

    Hello World

    程序从界面来说主要分为两大类:CLI(控制台)和GUI(图形界面)。
    控制台是一个简单的命令行程序,没有界面,执行没有界面,便于与其它命令组合,非常适合自动化批量执行。GUI则是一个包含界面的程序,易于非程序员操作和使用。下面使用wxWidgets各实现HelloWorld。

    控制台/终端

    #define WXUSINGDLL
    #define __WXMSW__
    #define _UNICODE
    #include <wx/wx.h>
    int main(){
        wxPrintf(wxT("HelloWorld"));
    }
    

    执行结果:HelloWorld

    对话框

    #define WXUSINGDLL
    #define __WXMSW__
    #define _UNICODE
    #include <wx/wx.h>
    int main(){
        wxMessageBox(wxT("HelloWorld"));
    }
    
    执行结果: 对话框

    在VisualStdio中,WXUSINGDLL__WXMSW___UNICODE三个宏通常设置在项目属性页的预处理定义中。

    窗口程序

    通常,使用wxWidgets就是要实现比较复杂的GUI界面,这种界面通常称为窗口。下面展示非常简单的一个窗口程序。

    #define WXUSINGDLL
    #define __WXMSW__
    #define _UNICODE
    
    #include <wx/wx.h>
    
    class MyFrame: public wxFrame {
    public:
        MyFrame(): wxFrame(NULL, wxID_ANY, "Hello World") {}
    };
    class MyApp: public wxApp {
    public:
        virtual bool OnInit(){
            MyFrame *pframe = new MyFrame();
            pframe->Show( true );
            return true;
        }
    };
    wxIMPLEMENT_APP(MyApp);
    
    执行结果: HelloWorld窗口

    特点:

    1. 没有main()函数,实际上是包含在wxWidgets框架中看不到。
    2. 一个应用程序类App,一个框架类Frame
    3. FrameAppOnInit()函数中实例化。

    注意:这里Frame没有销毁,可能会内存泄露(通常这么处理也不会有太大问题,因为窗口关闭时,OS会收回所有资源)。

    • 解决方法一:
      Frame指针作为App的成员变量,在App析构函数中释放Frame动态内存。
    #define WXUSINGDLL
    #define __WXMSW__
    #define _UNICODE
    #include <wx/wx.h>
    class MyFrame: public wxFrame {
    public:
        MyFrame(): wxFrame(NULL, wxID_ANY, "Hello World") {}
    };
    class MyApp: public wxApp {
    public:
        ~MyApp(){
            wxDELETE(pframe);
            wxASSERT(not pframe);
        }
        virtual bool OnInit(){
            pframe = new MyFrame();
            pframe->Show( true );
            return true;
        }
    private:
        MyFrame* pframe{nullptr};
    };
    wxIMPLEMENT_APP(MyApp);
    
    • 解决方法二:
      Frame对象作为App的成员变量,FrameApp生存周期自动的创建和消亡。
    #define WXUSINGDLL
    #define __WXMSW__
    #define _UNICODE
    #include <wx/wx.h>
    class MyFrame: public wxFrame {
    public:
        MyFrame(): wxFrame(NULL, wxID_ANY, "Hello World") {}
    };
    class MyApp: public wxApp {
    public:
        virtual bool OnInit(){
            frame.Show(true);
            return true;
        }
    private:
        MyFrame frame;
    };
    wxIMPLEMENT_APP(MyApp);
    

    添加状态栏

    #define WXUSINGDLL
    #define __WXMSW__
    #define _UNICODE
    
    #include <wx/wx.h>
    
    class MyFrame: public wxFrame {
    public:
        MyFrame(): wxFrame(NULL, wxID_ANY, "Hello World") {
            CreateStatusBar();
            SetStatusText( "Welcome to wxWidgets!" );
        }
    };
    class MyApp: public wxApp {
    public:
        virtual bool OnInit(){
            frame.Show(true);
            return true;
        }
    private:
        MyFrame frame;
    };
    wxIMPLEMENT_APP(MyApp);
    
    执行结果: 状态栏

    添加菜单

    #define WXUSINGDLL
    #define __WXMSW__
    #define _UNICODE
    
    #include <wx/wx.h>
    
    enum
    {
        ID_Hello = 1
    };
    
    class MyFrame: public wxFrame {
    public:
        MyFrame(): wxFrame(NULL, wxID_ANY, "Hello World") {
            // 菜单
            wxMenu *menuFile = new wxMenu;
            menuFile->Append(ID_Hello, "&Hello...\tCtrl-H",
                             "Help string shown in status bar for this menu item");
            menuFile->AppendSeparator();
            menuFile->Append(wxID_EXIT);
            
            // 菜单
            wxMenu *menuHelp = new wxMenu;
            menuHelp->Append(wxID_ABOUT);
    
            // 菜单栏
            wxMenuBar *menuBar = new wxMenuBar;
            menuBar->Append( menuFile, "&File" );
            menuBar->Append( menuHelp, "&Help" );
            SetMenuBar( menuBar );
    
            CreateStatusBar();
            SetStatusText( "Welcome to wxWidgets!" );
        }
    };
    class MyApp: public wxApp {
    public:
        virtual bool OnInit(){
            frame.Show(true);
            return true;
        }
    private:
        MyFrame frame;
    };
    wxIMPLEMENT_APP(MyApp);
    
    执行结果: 菜单栏

    菜单添加事件

    #define WXUSINGDLL
    #define __WXMSW__
    #define _UNICODE
    
    #pragma comment(lib,"vcruntime.lib")
    #include <wx/wx.h>
    
    enum
    {
        ID_Hello = 1
    };
    
    class MyFrame: public wxFrame {
    public:
        MyFrame(): wxFrame(NULL, wxID_ANY, "Hello World") {
            // 菜单
            wxMenu *menuFile = new wxMenu;
            menuFile->Append(ID_Hello, "&Hello...\tCtrl-H",
                             "Help string shown in status bar for this menu item");
            menuFile->AppendSeparator();
            menuFile->Append(wxID_EXIT);
            
            // 菜单
            wxMenu *menuHelp = new wxMenu;
            menuHelp->Append(wxID_ABOUT);
    
            // 菜单栏
            wxMenuBar *menuBar = new wxMenuBar;
            menuBar->Append( menuFile, "&File" );
            menuBar->Append( menuHelp, "&Help" );
            SetMenuBar( menuBar );
    
            CreateStatusBar();
            SetStatusText( "Welcome to wxWidgets!" );
    
            Bind(wxEVT_MENU, [=](wxCommandEvent&){wxLogMessage("Hello world from wxWidgets!");}, ID_Hello);
            Bind(wxEVT_MENU, [=](wxCommandEvent&){
                wxMessageBox( "This is a wxWidgets' Hello world sample","About Hello World", wxOK | wxICON_INFORMATION );
            }, wxID_ABOUT);
            Bind(wxEVT_MENU, [=](wxCommandEvent&){ Close(true);}, wxID_EXIT);
        }
    };
    class MyApp: public wxApp {
    public:
        virtual bool OnInit(){
            frame.Show(true);
            return true;
        }
    private:
        MyFrame frame;
    };
    wxIMPLEMENT_APP(MyApp);
    

    注意:这里的菜单栏和菜单项不要手动delete,Frame销毁时负责销毁。


    右键菜单

    #define WXUSINGDLL
    #define __WXMSW__
    #define _UNICODE
    #include <wx/wx.h>
    
    #pragma comment(lib,"vcruntime.lib")
    
    class MyFrame: public wxFrame {
    public:
        MyFrame(): wxFrame(NULL, wxID_ANY, "Hello World") {}
        void OnPopupMenu(wxMouseEvent& event){
            wxMenu menu;
            menu.Append(wxID_ANY,wxT("Test1"));
            menu.Append(wxID_ANY,wxT("Test2"));
            this->PopupMenu(&menu);
        }
    
        DECLARE_EVENT_TABLE()
    };
    BEGIN_EVENT_TABLE(MyFrame, wxFrame)
        EVT_RIGHT_DOWN(MyFrame::OnPopupMenu)
    END_EVENT_TABLE()
    
    class MyApp: public wxApp {
    public:
        virtual bool OnInit(){
            MyFrame* pFrame = new MyFrame;
            pFrame->Show( true );
            return true;
        }   
    };
    wxIMPLEMENT_APP(MyApp);
    
    #define WXUSINGDLL
    #define __WXMSW__
    #define _UNICODE
    #include <wx/wx.h>
    
    #pragma comment(lib,"vcruntime.lib")
    class MyPopupMenu: public wxMenu {
    public:
        MyPopupMenu():wxMenu(){
            Append(wxID_ANY,wxT("Test1"));
            Append(wxID_ANY,wxT("Test2"));
        }
    };
    
    class MyFrame: public wxFrame {
    public:
        MyFrame(): wxFrame(NULL, wxID_ANY, "Hello World") {}
        void OnPopupMenu(wxMouseEvent& event){
            MyMenu menu;
            PopupMenu(&menu);
        }
    
        DECLARE_EVENT_TABLE()
    };
    BEGIN_EVENT_TABLE(MyFrame, wxFrame)
        EVT_RIGHT_DOWN(MyFrame::OnPopupMenu)
    END_EVENT_TABLE()
    
    class MyApp: public wxApp {
    public:
        virtual bool OnInit(){
            MyFrame* pFrame = new MyFrame;
            pFrame->Show( true );
            return true;
        }   
    };
    wxIMPLEMENT_APP(MyApp);
    

    动态菜单

    #define WXUSINGDLL
    #define __WXMSW__
    #define _UNICODE
    #include <wx/wx.h>
    #include <vector>
    #include <tuple>
    
    using namespace std;
    
    #pragma comment(lib,"vcruntime.lib")
    
    class MyPopupMenu: public wxMenu {
    enum{
        ID_CREATE_PROJECT,
        ID_CREATE_GROUP,
        ID_CREATE_MARKPOINT,
        ID_CREATE_FOV_SINGLE,
        ID_CREATE_FOV_MAPPED,
        ID_COPY_PASTE,
        ID_DELETE,
        ID_SET_REPORT,
        ID_PROPERTY,
        ID_TEST
    };
    public:
        MyPopupMenu():wxMenu(){
            typedef void (MyPopupMenu::*MenuFunc)(wxCommandEvent&);
            typedef tuple<int,wxString,MenuFunc> MenuItem;
            vector<MenuItem> items = {
                make_tuple(ID_CREATE_PROJECT,wxT("创建工程"),&MyPopupMenu::OnCreateProject),
                make_tuple(ID_CREATE_GROUP, wxT("创建Group"),&MyPopupMenu::OnCreateGroup),
                make_tuple(ID_CREATE_MARKPOINT,wxT("创建MarkPoint"),&MyPopupMenu::OnCreateMarkPoint),
                make_tuple(ID_CREATE_FOV_SINGLE,wxT("创建FovSingle"),&MyPopupMenu::OnCreateFovSingle),
                make_tuple(ID_CREATE_FOV_MAPPED,wxT("创建FovMapped"),&MyPopupMenu::OnCreateFovMapped),
            };
    
            for(auto& item : items){
                MenuFunc pFunc;
                wxString label;
                int id;
                tie(id,label,pFunc) = item;
                wxMenuItem* pItem = new wxMenuItem(this,id,label);
                Connect(id,wxEVT_MENU,(wxObjectEventFunction)(wxEventFunction)static_cast<wxCommandEventFunction>(pFunc),NULL,this);
                Append(pItem);
            }
            
        }
        void OnCreateProject(wxCommandEvent& event);
        void OnCreateGroup(wxCommandEvent& event);
        void OnCreateMarkPoint(wxCommandEvent& event);
        void OnCreateFovSingle(wxCommandEvent& event);
        void OnCreateFovMapped(wxCommandEvent& event);
    };
    
    void MyPopupMenu::OnCreateProject(wxCommandEvent& event){
        wxMessageBox(wxT("Context"), wxT("创建工程"),wxOK | wxICON_INFORMATION,nullptr);
    }
    void MyPopupMenu::OnCreateGroup(wxCommandEvent& event){
        wxMessageBox(wxT("Context"), wxT("创建Group"),wxOK | wxICON_INFORMATION,nullptr);
    }
    void MyPopupMenu::OnCreateMarkPoint(wxCommandEvent& event){
        wxMessageBox(wxT("Context"), wxT("创建工程"),wxOK | wxICON_INFORMATION,nullptr);
    }
    void MyPopupMenu::OnCreateFovSingle(wxCommandEvent& event){
        wxMessageBox(wxT("Context"), wxT("创建工程"),wxOK | wxICON_INFORMATION,nullptr);
    }
    void MyPopupMenu::OnCreateFovMapped(wxCommandEvent& event){
        wxMessageBox(wxT("Context"), wxT("创建工程"),wxOK | wxICON_INFORMATION,nullptr);
    }
    
    
    class MyFrame: public wxFrame {
    public:
        MyFrame(): wxFrame(NULL, wxID_ANY, "Hello World") {}
        void OnPopupMenu(wxMouseEvent& event){
            MyPopupMenu menu;
            PopupMenu(&menu);
        }
    
        DECLARE_EVENT_TABLE()
    };
    BEGIN_EVENT_TABLE(MyFrame, wxFrame)
        EVT_RIGHT_DOWN(MyFrame::OnPopupMenu)
    END_EVENT_TABLE()
    
    class MyApp: public wxApp {
    public:
        virtual bool OnInit(){
            oFrame.Show( true );
            return true;
        }
    private:
        MyFrame oFrame;
    };
    wxIMPLEMENT_APP(MyApp);
    

    其中,Connect(id,wxEVT_MENU,(wxObjectEventFunction)(wxEventFunction)static_cast<wxCommandEventFunction>(pFunc),NULL,this);可以使用Bind(),更加简单Bind(wxEVT_MENU,pFunc,this,id);

    同样,以下三行代码

     wxMenuItem* pItem = new wxMenuItem(this,id,label);
                Connect(id,wxEVT_MENU,(wxObjectEventFunction)(wxEventFunction)static_cast<wxCommandEventFunction>(pFunc),NULL,this);
                Append(pItem);
    

    可以简写成

    Append(id,label);
    Bind(wxEVT_MENU,pFunc,this,id);
    

    进一步优化

    #define WXUSINGDLL
    #define __WXMSW__
    #define _UNICODE
    #include <wx/wx.h>
    #include <vector>
    #include <tuple>
    
    using namespace std;
    
    #pragma comment(lib,"vcruntime.lib")
    class MyMenuHandler;
    typedef void (MyMenuHandler::*MenuFunc)(wxCommandEvent&);
    typedef tuple<int,wxString,MenuFunc> MenuItem;
    
    class MyMenuHandler{
    enum{
        ID_CREATE_PROJECT,
        ID_CREATE_GROUP,
        ID_CREATE_MARKPOINT,
        ID_CREATE_FOV_SINGLE,
        ID_CREATE_FOV_MAPPED,
        ID_COPY_PASTE,
        ID_DELETE,
        ID_SET_REPORT,
        ID_PROPERTY,
        ID_TEST
    };
    private:
    
        vector<MenuItem> items;
        void OnCreateProject(wxCommandEvent& event){
            wxMessageBox(wxT("Context"), wxT("创建工程"),wxOK | wxICON_INFORMATION,nullptr);
        }
        void OnCreateGroup(wxCommandEvent& event){
            wxMessageBox(wxT("Context"), wxT("创建Group"),wxOK | wxICON_INFORMATION,nullptr);
        }
        void OnCreateMarkPoint(wxCommandEvent& event){
            wxMessageBox(wxT("Context"), wxT("创建工程"),wxOK | wxICON_INFORMATION,nullptr);
        }
        void OnCreateFovSingle(wxCommandEvent& event){
            wxMessageBox(wxT("Context"), wxT("创建工程"),wxOK | wxICON_INFORMATION,nullptr);
        }
        void OnCreateFovMapped(wxCommandEvent& event){
            wxMessageBox(wxT("Context"), wxT("创建工程"),wxOK | wxICON_INFORMATION,nullptr);
        }
    public:
        MyMenuHandler():items({
                make_tuple(ID_CREATE_PROJECT,wxT("创建工程"),&MyMenuHandler::OnCreateProject),
                make_tuple(ID_CREATE_GROUP, wxT("创建Group"),&MyMenuHandler::OnCreateGroup),
                make_tuple(ID_CREATE_MARKPOINT,wxT("创建MarkPoint"),&MyMenuHandler::OnCreateMarkPoint),
                make_tuple(ID_CREATE_FOV_SINGLE,wxT("创建FovSingle"),&MyMenuHandler::OnCreateFovSingle),
                make_tuple(ID_CREATE_FOV_MAPPED,wxT("创建FovMapped"),&MyMenuHandler::OnCreateFovMapped)
        }){}
        vector<MenuItem>& GetHandlers(){
            return items;
        }
    };
    
    
    class MyPopupMenu: public wxMenu {
    public:
        enum{
            MENU_ID,MENU_LABEL,MENU_HAMDLE
        };
        MyPopupMenu(wxWindow* parent,MyMenuHandler&& handler):MyPopupMenu(parent,handler){}
        MyPopupMenu(wxWindow* parent,MyMenuHandler& handler):wxMenu(){
            for(auto& item : handler.GetHandlers()){
                Append(get<MENU_ID>(item),get<MENU_LABEL>(item));
                Bind(wxEVT_MENU,get<MENU_HAMDLE>(item),&handler,get<MENU_ID>(item));
            }
            parent->PopupMenu(this);
        }
    };
    
    class MyFrame: public wxFrame {
    public:
        MyFrame(): wxFrame(NULL, wxID_ANY, "Hello World") {}
        void OnPopupMenu(wxMouseEvent& event){
            MyPopupMenu menu(this,MyMenuHandler{});
        }
        DECLARE_EVENT_TABLE()
    };
    
    BEGIN_EVENT_TABLE(MyFrame, wxFrame)
        EVT_RIGHT_DOWN(MyFrame::OnPopupMenu)
    END_EVENT_TABLE()
    
    class MyApp: public wxApp {
    public:
        virtual bool OnInit(){
            oFrame.Show( true );
            return true;
        }
    private:
        MyFrame oFrame;
    };
    wxIMPLEMENT_APP(MyApp);
    

    相关文章

      网友评论

        本文标题:wxWidget之HelloWorld

        本文链接:https://www.haomeiwen.com/subject/cbzxvxtx.html