zoukankan      html  css  js  c++  java
  • [ZETCODE]wxWidgets教程九:组件专题2

    本教程原文链接:http://zetcode.com/gui/wxwidgets/widgetsII/

    翻译:瓶哥

    日期:2013年12月15日星期日

    邮箱:414236069@qq.com

    主页:http://www.cnblogs.com/pingge/

    若有翻译错误或者歧义请联系我!

    在这一章中,我们会继续介绍一些组件的知识,我们会提到wxListBox,wxNotebool和wxScrolledWindow。

    wxListBox

    一个wxListBox组件被用来显示一些元素,它是一个有一系列字符串的矩形。我们可以使用它来显示一个MP3文件的列表,一些书名,或者是一个大工程的模块名。一个wxListBox可以以两种不同的状态被创建。一个单一选择的状态或者一个多重选择的状态。单一状态是默认的状态,在wxListBox里面有两个事件类型,第一个是wxEVT_COMMAND_LISTBOX_SELECTED,当我们选择wxListBox里面的一个元素时这个事件产生;第二个是wxEVT_COMMAND_LISTBOX_DOUBLE_CLICKED,当我们双击wxListBox里面的一个元素时这个事件产生。在wxListBox内部的元素在GTK的平台上有限制,大概不能超过2000个左右的元素。元素的ID从0开始计算,滚动条会在需要的时候自动生成。

    listbox.h

    #include <wx/wx.h>
    #include <wx/listbox.h>
    
    class MyPanel : public wxPanel
    {
    public:
        MyPanel(wxPanel * parent);
    
        void OnNew(wxCommandEvent & event);
        void OnRename(wxCommandEvent & event);
        void OnClear(wxCommandEvent & event);
        void OnDelete(wxCommandEvent & event);
    
        wxListBox * m_lb;
    
        wxButton * m_newb;
        wxButton * m_renameb;
        wxButton * m_clearb;
        wxButton * m_deleteb;
    };
    
    class Listbox : public wxFrame
    {
    public:
        Listbox(const wxString & title);
    
        void OnDbClick(wxCommandEvent & event);
    
        wxListBox * listbox;
        MyPanel * btnPanel;
    };
    
    enum{ID_RENAME, ID_LISTBOX};
    

    listbox.cpp

    #include "listbox.h"
    #include <wx/textdlg.h>
    
    Listbox::Listbox(const wxString & title)
           : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(270, 200))
    {
        wxPanel * panel = new wxPanel(this, wxID_ANY);
    
        wxBoxSizer * hbox = new wxBoxSizer(wxHORIZONTAL);
    
        listbox = new wxListBox(panel, ID_LISTBOX, wxDefaultPosition, wxDefaultSize);
    
        btnPanel = new MyPanel(panel);
    
        hbox->Add(listbox, 3, wxEXPAND | wxALL, 20);
    
    
        hbox->Add(btnPanel, 2, wxEXPAND | wxRIGHT, 10);
    
        Connect(wxEVT_COMMAND_LISTBOX_DOUBLECLICKED,
                wxCommandEventHandler(Listbox::OnDbClick));
    
        panel->SetSizer(hbox);
    
        Centre();
    }
    
    MyPanel::MyPanel(wxPanel * parent)
           : wxPanel(parent, wxID_ANY)
    {
        wxBoxSizer * vbox = new wxBoxSizer(wxVERTICAL);
    
        // GetParent()方法获得了panel的父组件的地址
        Listbox * lb = (Listbox*)parent->GetParent();
    
        m_lb = lb->listbox;
    
        m_newb = new wxButton(this, wxID_NEW, _T("New"));
        m_renameb = new wxButton(this, ID_RENAME, _T("Rename"));
        m_deleteb = new wxButton(this, wxID_DELETE, _T("Delete"));
        m_clearb = new wxButton(this, wxID_CLEAR, _T("Clear"));
    
        Connect(wxID_NEW, wxEVT_COMMAND_BUTTON_CLICKED,
                wxCommandEventHandler(MyPanel::OnNew) );
        Connect(ID_RENAME, wxEVT_COMMAND_BUTTON_CLICKED,
                wxCommandEventHandler(MyPanel::OnRename) );
        Connect(wxID_CLEAR, wxEVT_COMMAND_BUTTON_CLICKED,
                wxCommandEventHandler(MyPanel::OnClear) );
        Connect(wxID_DELETE, wxEVT_COMMAND_BUTTON_CLICKED,
                wxCommandEventHandler(MyPanel::OnDelete) );
    
        vbox->Add(-1, 20);
        vbox->Add(m_newb);
        vbox->Add(m_renameb, 0, wxTOP, 5);
        vbox->Add(m_deleteb, 0, wxTOP, 5);
        vbox->Add(m_clearb, 0, wxTOP, 5);
    
        SetSizer(vbox);
    }
    
    void MyPanel::OnNew(wxCommandEvent & event)
    {
        wxString str = wxGetTextFromUser(_T("Add new item"));
        if(str.Len() > 0)
        {
            m_lb->Append(str);
        }
    }
    
    void MyPanel::OnClear(wxCommandEvent & event)
    {
        m_lb->Clear();
    }
    
    void MyPanel::OnRename(wxCommandEvent & event)
    {
        wxString text;
        wxString renamed;
    
        int sel = m_lb->GetSelection();
        if(sel != -1)
        {
            text = m_lb->GetString(sel);
            renamed = wxGetTextFromUser(_T("Rename item"), _T("Rename dialog"), text);
        }
        if(!renamed.IsEmpty())
        {
            m_lb->Delete(sel);
            m_lb->Insert(renamed, sel);
        }
    }
    
    void MyPanel::OnDelete(wxCommandEvent & event)
    {
        int sel = m_lb->GetSelection();
        if(sel != -1)
        {
            m_lb->Delete(sel);
        }
    }
    
    void Listbox::OnDbClick(wxCommandEvent & event)
    {
        wxString text;
        wxString renamed;
    
        int sel = listbox->GetSelection();
        if(sel != -1)
        {
            text = listbox->GetString(sel);
            renamed = wxGetTextFromUser(_T("Rename item"), _T("Rename dialog"), text);
        }
        if(!renamed.IsEmpty())
        {
            listbox->Delete(sel);
            listbox->Insert(renamed, sel);
        }
    }
    

    main.h

    #include <wx/wx.h>
    
    class MyApp : public wxApp
    {
    public:
        virtual bool OnInit();
    };
    

    main.cpp

    #include "main.h"
    #include "Listbox.h"
    
    IMPLEMENT_APP(MyApp)
    
    bool MyApp::OnInit()
    {
        Listbox * listbox = new Listbox(_T("Listbox"));
        listbox->Show(true);
    
        return true;
    }
    

    listbox = new wxListBox(panel, ID_LISTBOX, wxDEFAULT_POSITION, wxDEFAULT_SIZE);

    这个是listbox组件的构造器.

    在我们的例子中,我们有一列四个按钮,这些按钮用来在listbox内添加、修改、删除、清空元素。

    wxString str = wxGetTextFromUser(_T("Add new item"));

    if(str.Len() > 0)

    {m_lb->Append(str);

    }

    我们使用上面的代码显示一个wxGetTextFromUser对话框接收用户输入,然后调用Append()函数添加到listbox内。

    m_lb->Clear();

    清空listbox只需要简单的调用一个Clear()方法。

    int sel = m_lb->GetSelection();

    if(sel != -1)

    {m_lb->Delete(sel);

    }

    我们调用GetSelection()方法计算出当前选中的是第几项,然后我们调用Delete()方法删除元素。

    修改一个元素需要以下几个步骤:

    wxString text;

    wxString renamed;

    我们定义了两个字符串对象。

    int sel = listbox->GetSelection();

    if(sel != -1)

    {text = listbox->GetString(sel);

    Renamed = wxGetTextFromUser(_T("Rename item"), _T("Rename dialog"), text);

    }

    我们获取了当前选中的的字符串,并保存起来,然后请求用户的输入。

    if(!renamed.IsEmpty())

    {m_lb->Delete(sel);

    m_lb->Insert(renamed, sel);

    }

    我们检查了renamed字符串是否为空,避免了插入空字符串,然后我们删除了旧的元素,插入新的元素。

    wxNotebook

    wxNotebook可以在一个窗体上通过标签列举多个窗口。可以通过下面四个标识符指定标签的位置:

    1. wxNB_LEFT
    2. wxNB_RIGHT
    3. wxNB_TOP
    4. wxNB_BOTTOM

    默认的是wxNB_TOP

    notebook.h

    #include <wx/wx.h>
    #include <wx/notebook.h>
    #include <wx/grid.h>
    
    class Notebook : public wxFrame
    {
    public:
        Notebook(const wxString & title);
    
        void OnQuit(wxCommandEvent & event);
    };
    
    class MyGrid : public wxGrid
    {
    public:
        MyGrid(wxNotebook * parent);
    };
    

    notebook.cpp

    #include "notebook.h"
    
    Notebook::Notebook(const wxString & title)
            : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(400, 350))
    {
        wxNotebook * nb = new wxNotebook(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxNB_BOTTOM);
    
        wxMenuBar * menubar = new wxMenuBar();
        wxMenu * file = new wxMenu();
        file->Append(wxID_EXIT, _T("Quit"), _T(""));
        menubar->Append(file, _T("&File"));
        SetMenuBar(menubar);
    
        Connect(wxEVT_COMMAND_MENU_SELECTED,
                wxCommandEventHandler(Notebook::OnQuit));
        MyGrid * grid1 = new MyGrid(nb);
        MyGrid * grid2 = new MyGrid(nb);
        MyGrid * grid3 = new MyGrid(nb);
    
        nb->AddPage(grid1, _T("Sheet1"));
        nb->AddPage(grid2, _T("Sheet2"));
        nb->AddPage(grid3, _T("Sheet3"));
    
        CreateStatusBar();
        Centre();
    }
    
    void Notebook::OnQuit(wxCommandEvent & event)
    {
        Close(true);
    }
    
    MyGrid::MyGrid(wxNotebook * parent)
          : wxGrid(parent, wxID_ANY)
    {
        CreateGrid(30, 30);
        SetRowLabelSize(50);
        SetColLabelSize(25);
        SetRowLabelAlignment(wxALIGN_RIGHT, wxALIGN_CENTER);
        SetLabelFont(wxFont(9, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD));
    
        for(int i = 0; i < 30; i++)
        {
            this->SetRowSize(i, 25);
        }
    }
    

    main.h

    #include <wx/wx.h>
    
    class MyApp : public wxApp
    {
    public:
        virtual bool OnInit();
    };
    

    main.cpp

    #include "main.h"
    #include "notebook.h"
    
    IMPLEMENT_APP(MyApp)
    
    bool MyApp::OnInit()
    {
        Notebook * notebook = new Notebook(_T("Notebook"));
        notebook->Show(true);
    
        return true;
    }
    

    在这个例子中,我们创建了一个包含三个表格控件的notebook组件,notebook的标签被放置在窗体底部。

    wxNotebook * nb = new wxNotebook(this, wxID_ANY, wxDEFAULTPOSITION, wxDEFAULTSIZE, wxNB_BOTTOM);

    这里我们创建了一个notebook组件。

    nb->AddPage(grid1, _T("Sheet1"));

    nb->AddPage(grid2, _T("Sheet2"));

    nb->AddPage(grid3, _T("Sheet3"));

    我们添加了三个表格控件到notebook组件中。

    wxScrolledWindow

    这是容器组件中的其中一个。当我们有一个比屏幕还要大的区域需要显示时,这个组件很有用。在我们的例子中,我们示范了它的用法,我们在窗口中放置了一个巨大的图片。当窗口比我们的图片小的时候,滚动条会自动显示。

    scrolledwindow.h

    #include <wx/wx.h>
    
    class ScrolledWindow : public wxFrame
    {
    public:
        ScrolledWindow(const wxString & title);
    };
    

    scrolledwindow.cpp

    #include "scrolledwindow.h"
    
    ScrolledWindow::ScrolledWindow(const wxString & title)
             : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(300, 200))
    {
        wxImage::AddHandler(new wxJPEGHandler);
    
        wxScrolledWindow * sw = new wxScrolledWindow(this);
    
        wxBitmap bmp(_T("test.jpg"), wxBITMAP_TYPE_JPEG);
        wxStaticBitmap * sb = new wxStaticBitmap(sw, -1, bmp);
    
        int width = bmp.GetWidth();
        int height = bmp.GetHeight();
    
        sw->SetScrollbars(10, 10, width / 10, height / 10);
        sw->Scroll(50, 10);
    
        Centre();
    }
    

    main.h

    #include <wx/wx.h>
    
    class MyApp : public wxApp
    {
    public:
        virtual bool OnInit();
    };
    

    main.cpp

    #include "main.h"
    #include "scrolledwindow.h"
    
    IMPLEMENT_APP(MyApp)
    
    bool MyApp::OnInit()
    {
        ScrolledWindow * sw = new ScrolledWindow(_T("ScrolledWindow"));
        sw->Show(true);
    
        return true;
    }
    

      

    在我们的例子中,我们显示了一张海贼王的图片。

    wxImage::AddHandler(new wxJPEGHandler);

    我们必须初始化wxJPEGHandler,才能处理jpg图像。

    wxScrolledWindow * sw = new wxScrolledWindow(this);

    wxBitmap bmp(_T("test.jpg"), wxBITMAP_TYPE_JPEG);

    wxStaticBitmap * sb = new wxStaticBitmap(sw, -1, bmp);

    我们创建了一个滚动窗口,并放置了一张静态图。

    sw->SetScrollbars(10, 10, width / 10, height / 10);

    我们设置了滚动条。

    sw->Scroll(50, 10);

    滚动到初始位置。

    在这一章中,我们继续介绍了wxWidgets库中的组件。

  • 相关阅读:
    hdu5728 PowMod
    CF1156E Special Segments of Permutation
    CF1182E Product Oriented Recurrence
    CF1082E Increasing Frequency
    CF623B Array GCD
    CF1168B Good Triple
    CF1175E Minimal Segment Cover
    php 正则
    windows 下安装composer
    windows apache "The requested operation has failed" 启动失败
  • 原文地址:https://www.cnblogs.com/pingge/p/3476520.html
Copyright © 2011-2022 走看看