• [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库中的组件。

  • 相关阅读:
    刷题笔记
    布隆过滤器
    单例模式,堆,BST,AVL树,红黑树
    B树、B-树、B+树、B*树【转】,mysql索引
    数据结构与算法80道
    海量数据处理【转】
    volcanol的工控博客
    volcanol的工控博客
    volcanol的工控博客
    volcanol的工控博客
  • 原文地址:https://www.cnblogs.com/pingge/p/3476520.html
Copyright © 2020-2023  润新知