Tartalomjegyzék

< wxWidgets kézikönyv

Widgets

Ebben a részben, kisebb példákon keresztül több widgetet mutatunk be, amelyek elérhetők a wxWidgets-ben. A widgetek blokkjaiból épülnek fel az alkalmazásaink. A wxWidgets nagyszámú hasznos widgetet tartalmaz. A Widget, definíciója szerint, egy alap GUI objektum. Egy widget szó szerepel a wxWdigets eszközkészlet nevében. Ez a terminológia a UNIX rendszerekből származik. Windowson, egy widget rendszerint egy kontroll (control).

wxCheckBox

wxCheckBox is a widget that has two states. On and Off. It is a box with a label. The label can be set to the right or to the left of the box. If the checkbox is checked, it is represented by a tick in a box. A checkbox can be used to show/hide splashscreen at startup, toggle visibility of a toolbar etc.

A wxCheckBox egy widget, amelynek két állapota van. Kikapcsolt és bekapcsolt (on és off). Egy doboz, amelynek van egy felirata. A felirat lehet a doboztól jobbra vagy balra. Ha a jelölőnégyzet (checkbox), ha ki van pipálva (checked), a dobozban egy kis pipa jelöli. A jelölőnégyzet használható az indítóképernyő rejtésére, megjelenítésére, az eszköztár láthatóságának jelölésére stb.

checkbox.h
#include <wx/wx.h>
 
class CheckBox : public wxFrame
{
public:
      CheckBox(const wxString& title);
 
      void OnToggle(wxCommandEvent& event);
 
      wxCheckBox *m_cb;
 
};
 
const int ID_CHECKBOX = 100;
checkbox.cpp
#include "checkbox.h"
 
CheckBox::CheckBox(const wxString& title)
       : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(270, 150))
{
    wxPanel *panel = new wxPanel(this, wxID_ANY);
 
    m_cb = new wxCheckBox(panel, ID_CHECKBOX, wxT("Show title"), 
                          wxPoint(20, 20));
    m_cb->SetValue(true);
    Connect(ID_CHECKBOX, wxEVT_COMMAND_CHECKBOX_CLICKED, 
            wxCommandEventHandler(CheckBox::OnToggle));
    Centre();
}
 
void CheckBox::OnToggle(wxCommandEvent& WXUNUSED(event))
{
 
    if (m_cb->GetValue()) {
        this->SetTitle(wxT("CheckBox"));
    } else {
        this->SetTitle(wxT(" "));
    }
}
main.h
#include <wx/wx.h>
 
class MyApp : public wxApp
{
  public:
      virtual bool OnInit();
};
main.cpp
#include "main.h"
#include "checkbox.h"
 
IMPLEMENT_APP(MyApp)
 
bool MyApp::OnInit()
{
 
      CheckBox *cb = new CheckBox(wxT("CheckBox"));
      cb->Show(true);
 
      return true;
}

A példánkban, megjelenítünk egy jelölőnégyzetet az ablakon. A jelölőnégyzetre kattintva válthatjuk az ablak címét.

m_cb = new wxCheckBox(panel, ID_CHECKBOX, wxT("Show title"), 
                     wxPoint(20, 20));
m_cb->SetValue(true);

Készítünk egy jelölőnégyzetet. Alapértelmezetten a felirat látható. A SetValue() metódus meghívásával állítjuk be a jelölőnégyzetet.

Connect(ID_CHECKBOX, wxEVT_COMMAND_CHECKBOX_CLICKED, 
       wxCommandEventHandler(CheckBox::OnToggle));

Ha kattintunk a jelölőnégyzeten, a wxEVT_COMMAND_CHECKBOX_CLICKED esemény generálódik. Az eseményhez kapcsolhatjuk, a felhasználó által megadott OnToggle() metódust.

if (m_cb->GetValue()) 
{
    this->SetTitle(wxT("CheckBox"));
} else {
    this->SetTitle(wxT(" "));
}

Az OnToggle() metóduson belül, ellenőrizzük a jelölőnégyzet állapotát. Ha az be van állítva (checked), akkor megjelenítjük a „CheckBox” szöveget, a címsorban, ellenkező esetben töröljük azt.

wxCheckBox 

Figure: wxCheckBox

wxBitmapButton

A bitmap button egy gomb, amely megjelenít egy képet. Ezen kívül, a bitmap button három állapottal rendelkezik. Kiválasztott, fókuszban és megjelenített. Minden állapot számára beállíthatunk egy külön képet.

bitmapbutton.h
#include <wx/wx.h>
#include <wx/slider.h>
 
class BitmapButton : public wxFrame
{
  public:
    BitmapButton(const wxString& title);
 
    wxSlider *slider;
    wxBitmapButton *button;
    int pos;
 
    void OnScroll(wxScrollEvent& event);
 
};
 
const int ID_SLIDER = 100;
bitmapbutton.cpp
#include "bitmapbutton.h"
 
BitmapButton::BitmapButton(const wxString& title)
       : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(250, 130))
{
    wxImage::AddHandler( new wxPNGHandler );
    wxPanel *panel = new wxPanel(this);
    slider = new wxSlider(panel, ID_SLIDER, 0, 0, 100, 
        wxPoint(10, 30), wxSize(140, -1));
 
    button = new wxBitmapButton(panel, wxID_ANY, wxBitmap(wxT("mute.png"), 
        wxBITMAP_TYPE_PNG), wxPoint(180, 20));
 
    Connect(ID_SLIDER, wxEVT_COMMAND_SLIDER_UPDATED, 
        wxScrollEventHandler(BitmapButton::OnScroll));  
    Center();
}
 
 
void BitmapButton::OnScroll(wxScrollEvent& event)
{
    pos = slider->GetValue(); 
 
    if (pos == 0) {
        button->SetBitmapLabel(wxBitmap(wxT("mute.png"), wxBITMAP_TYPE_PNG));
    } else if (pos > 0 && pos <= 30 ) {
        button->SetBitmapLabel(wxBitmap(wxT("min.png"), wxBITMAP_TYPE_PNG));
    } else if (pos > 30 && pos < 80 ) {
        button->SetBitmapLabel(wxBitmap(wxT("med.png"), wxBITMAP_TYPE_PNG));
    } else {
        button->SetBitmapLabel(wxBitmap(wxT("max.png"), wxBITMAP_TYPE_PNG));
    }
}
main.h
#include <wx/wx.h>
 
class MyApp : public wxApp
{
  public:
      virtual bool OnInit();
};
main.cpp
#include "main.h"
#include "bitmapbutton.h"
 
IMPLEMENT_APP(MyApp)
 
bool MyApp::OnInit()
{
 
      BitmapButton *bb = new BitmapButton(wxT("BitmapButton"));
      bb->Show(true);
 
      return true;
}

A példánkban, van egy slider és egy bitmap button. Szimulálunk a hangerőszabályozót. A csúszka fogantyújának húzásával megváltoztatjuk a gomb bitképét.

wxImage::AddHandler( new wxPNGHandler );

We will use PNG images, so we must initialize a PNG image handler.

button = new wxBitmapButton(panel, wxID_ANY, wxBitmap(wxT("mute.png"), 
    wxBITMAP_TYPE_PNG), wxPoint(180, 20));

Készítünk egy bitmap button-t. Megadjuk a bitmap típusát, ami az esetünkben wxBITMAP_TYPE_PNG.

pos = slider->GetValue(); 

Megkapjuk a slider étékét. Ettől az értéktől függ, milyen képet állítunk be a gomb számára. A hangerő szabályozónak, négy állapota van. Néma, minimuk, közepes és maximum. A gomb képének megváltoztatásához használjuk a SetBitmapLabel() függvényt.

wxToggleButton

A wxToggleButton egy gomb két állapottal. Lenyomott és nem lenyomott. A két állapot között a kattitnással válthatunk. Vannak helyzetek, amikor ezek nagyon jól jönnek.

togglebutton.h
#include <wx/wx.h>
#include <wx/tglbtn.h>
 
class ToggleButton : public wxFrame
{
  public:
    ToggleButton(const wxString& title);
 
    void OnToggleRed(wxCommandEvent& event);
    void OnToggleGreen(wxCommandEvent& event);
    void OnToggleBlue(wxCommandEvent& event);
 
  protected:
    wxToggleButton *m_tgbutton1;
    wxToggleButton *m_tgbutton2;
    wxToggleButton *m_tgbutton3;
 
    wxPanel *m_panel;
    wxColour *colour;
 
};
 
const int ID_TGBUTTON1 = 101;
const int ID_TGBUTTON2 = 102;
const int ID_TGBUTTON3 = 103;
togglebutton.cpp
#include "togglebutton.h"
 
ToggleButton::ToggleButton(const wxString& title)
         : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(280, 180))
{
    wxPanel *panel = new wxPanel(this, wxID_ANY);
 
    colour = new wxColour(0, 0, 0);
 
    m_tgbutton1 = new wxToggleButton(panel, ID_TGBUTTON1, 
                                     wxT("Red"), wxPoint(20, 20));
    m_tgbutton2 = new wxToggleButton(panel, ID_TGBUTTON2, 
                                     wxT("Green"), wxPoint(20, 70));
    m_tgbutton3 = new wxToggleButton(panel, ID_TGBUTTON3, 
                                     wxT("Blue"), wxPoint(20, 120));
 
    Connect(ID_TGBUTTON1, wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, 
        wxCommandEventHandler(ToggleButton::OnToggleRed));
    Connect(ID_TGBUTTON2, wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, 
        wxCommandEventHandler(ToggleButton::OnToggleGreen));
    Connect(ID_TGBUTTON3, wxEVT_COMMAND_TOGGLEBUTTON_CLICKED,  
        wxCommandEventHandler(ToggleButton::OnToggleBlue));
 
    m_panel = new wxPanel(panel, wxID_NEW, wxPoint(150, 20), 
                          wxSize(110, 110), wxSUNKEN_BORDER);
    m_panel->SetBackgroundColour(colour->GetAsString());
 
}
 
void ToggleButton::OnToggleRed(wxCommandEvent& WXUNUSED(event))
{
    unsigned char green = colour->Green(); 
    unsigned char blue = colour->Blue(); 
 
 
    if ( colour->Red() ) {
        colour->Set(0, green, blue);
 
    } else { 
        colour->Set(255, green, blue);
    }
 
    m_panel->SetBackgroundColour(colour->GetAsString());
 
}
 
void ToggleButton::OnToggleGreen(wxCommandEvent& WXUNUSED(event))
{
    unsigned char red = colour->Red(); 
    unsigned char blue = colour->Blue(); 
 
 
    if ( colour->Green() ) {
        colour->Set(red, 0, blue);
 
    } else { 
        colour->Set(red, 255, blue);
    }
 
    m_panel->SetBackgroundColour(colour->GetAsString());
 
}
 
void ToggleButton::OnToggleBlue(wxCommandEvent& WXUNUSED(event))
{
    unsigned char red = colour->Red(); 
    unsigned char green = colour->Green(); 
 
 
    if ( colour->Blue() ) {
        colour->Set(red, green, 0);
 
    } else { 
        colour->Set(red, green, 255);
    }
 
    m_panel->SetBackgroundColour(colour->GetAsString());
}
main.h
#include <wx/wx.h>
 
class MyApp : public wxApp
{
    public:
      virtual bool OnInit();
};
main.cpp
#include "main.h"
#include "togglebutton.h"
 
IMPLEMENT_APP(MyApp)
 
bool MyApp::OnInit()
{
 
      ToggleButton *button = new ToggleButton(wxT("ToggleButton"));
 
      button->Centre();
      button->Show(true);
 
      return true;
}

A példánkan, három toggle button van egy panelen. A panel háttérszínét feketére állítjuk. A benyomható gombok egy színértékhez biztosítanak piros, zöld és kék értékeket. A háttérszín, attól függ, melyik gomb van lenyomva.

colour = new wxColour(0, 0, 0);

Ez a kezdő szín értéke. Nincs piros, zöld és kék, ez feketét eredményez.

m_tgbutton1 = new wxToggleButton(panel, ID_TGBUTTON1, 
                                wxT("Red"), wxPoint(20, 20));

Here we create a toggle button.

Connect(ID_TGBUTTON1, wxEVT_COMMAND_TOGGLEBUTTON_CLICKED, 
    wxCommandEventHandler(ToggleButton::OnToggleRed));

Ha kattintunk a lenyomható gombra, a wxEVT_COMMAND_TOGGLEBUTTON_CLICKED esemény generálódik. Kapcsolódunk ehhez az eseményhez. Jegyezzük meg, hogy gombhoz nem kapcsolunk függvényt, de a wxFrame-hez igen. Egy widget, amely szülője, a lenyomható gomboknak. Ezt megtehetjük, mert az parancseseményeket a szüleik terjesztik. Ebben az esetben, button → panel → frame. Ha szeretnénk kapcsolódni egy gombeseményhez, létre kell hozni egy származtatott gombosztályt, ami több munkát jelentene.

  if ( colour->Blue() ) {
      colour->Set(red, green, 0);
 
  } else { 
      colour->Set(red, green, 255);
  }

Az eseménykezelőben, beállítjuk a wxColour paramétereit.

m_panel->SetBackgroundColour(colour->GetAsString());

Beállítjuk a panel háttérszínét.

wxStaticLine

Ez a widget egy egyszerű vonalat jelenít meg az ablakon. Ez lehet vízszintes és függőleges.

staticline.h
#include <wx/wx.h>
 
class Staticline : public wxDialog
{
public:
    Staticline(const wxString& title);
 
};
staticline.cpp
#include "staticline.h"
#include <wx/stattext.h>
#include <wx/statline.h>
 
Staticline::Staticline(const wxString& title) : wxDialog(NULL, wxID_ANY, title, 
    wxDefaultPosition, wxSize(360, 350))
{
 
    wxFont font(10, wxDEFAULT, wxNORMAL, wxBOLD);
    wxStaticText *heading = new wxStaticText(this, wxID_ANY, wxT("The Central Europe"), 
        wxPoint(30, 15));
    heading->SetFont(font);
 
    wxStaticLine *sl1 = new wxStaticLine(this, wxID_ANY, wxPoint(25, 50), 
        wxSize(300,1));
 
    wxStaticText *st1 = new wxStaticText(this, wxID_ANY, wxT("Slovakia"), 
        wxPoint(25, 80));
    wxStaticText *st2 = new wxStaticText(this, wxID_ANY, wxT("Hungary"), 
        wxPoint(25, 100));
    wxStaticText *st3 = new wxStaticText(this, wxID_ANY, wxT("Poland"), 
        wxPoint(25, 120));
    wxStaticText *st4 = new wxStaticText(this, wxID_ANY, wxT("Czech Republic"), 
        wxPoint(25, 140));
    wxStaticText *st5 = new wxStaticText(this, wxID_ANY, wxT("Germany"), 
        wxPoint(25, 160));
    wxStaticText *st6 = new wxStaticText(this, wxID_ANY, wxT("Slovenia"), 
        wxPoint(25, 180));
    wxStaticText *st7 = new wxStaticText(this, wxID_ANY, wxT("Austria"), 
        wxPoint(25, 200));
    wxStaticText *st8 = new wxStaticText(this, wxID_ANY, wxT("Switzerland"), 
        wxPoint(25, 220));
 
 
    wxStaticText *st9  = new wxStaticText(this, wxID_ANY, wxT("5 379 000"), 
        wxPoint(220, 80), wxSize(90, -1), wxALIGN_RIGHT);
    wxStaticText *st10 = new wxStaticText(this, wxID_ANY, wxT("10 084 000"), 
        wxPoint(220, 100), wxSize(90, -1), wxALIGN_RIGHT);
    wxStaticText *st11 = new wxStaticText(this, wxID_ANY, wxT("38 635 000"), 
        wxPoint(220, 120), wxSize(90, -1), wxALIGN_RIGHT);
    wxStaticText *st12 = new wxStaticText(this, wxID_ANY, wxT("10 240 000"), 
        wxPoint(220, 140), wxSize(90, -1), wxALIGN_RIGHT);
    wxStaticText *st13 = new wxStaticText(this, wxID_ANY, wxT("82 443 000"), 
        wxPoint(220, 160), wxSize(90, -1), wxALIGN_RIGHT);
    wxStaticText *st14 = new wxStaticText(this, wxID_ANY, wxT("2 001 000"),  
        wxPoint(220, 180), wxSize(90, -1), wxALIGN_RIGHT);
    wxStaticText *st15 = new wxStaticText(this, wxID_ANY, wxT("8 032 000"),  
        wxPoint(220, 200), wxSize(90, -1), wxALIGN_RIGHT);
    wxStaticText *st16 = new wxStaticText(this, wxID_ANY, wxT("7 288 000"),  
        wxPoint(220, 220), wxSize(90, -1), wxALIGN_RIGHT);
 
    wxStaticLine *sl2 = new wxStaticLine(this, wxID_ANY, wxPoint(25, 260), 
        wxSize(300, 1));
 
    wxStaticText *sum = new wxStaticText(this, wxID_ANY, wxT("164 102 000"), 
        wxPoint(220, 280));
    wxFont sum_font = sum->GetFont();
    sum_font.SetWeight(wxBOLD);
    sum->SetFont(sum_font);
 
    this->Centre();
 
}
main.h
#include <wx/wx.h>
 
class MyApp : public wxApp
{
    public:
      virtual bool OnInit();
}; 
main.cpp
#include "main.h"
#include "staticline.h"
 
IMPLEMENT_APP(MyApp)
 
bool MyApp::OnInit()
{
      Staticline *sl = new Staticline(wxT("The Central Europe"));
      sl->ShowModal();
      sl->Destroy();
 
      return true;
}

Az előző példában, megjelenítettünk közép-európai országokat és népességüket. A wxStaticLine használata vizuálisan vonzóbbá teszi.

  wxStaticLine *sl1 = new wxStaticLine(this, wxID_ANY, wxPoint(25, 50), 
     wxSize(300,1));

Itt készítettünk egy vízszintes statikus vonalat. 300 pixel széles. A magassága 1 pixel.

wxStaticText

A wxStaticText widget displays one or more lines of read-only text.

A wxStatiText widget, csak olvasható szöveget jelenít meg egy vagy több sorban.

statictext.h
#include <wx/wx.h>
 
class StaticText : public wxFrame
{
public:
    StaticText(const wxString& title);
 
};
statictext.cpp
#include "statictext.h"
 
StaticText::StaticText(const wxString& title)
         : wxFrame(NULL, wxID_ANY, title)
{
 
    wxPanel *panel = new wxPanel(this, wxID_ANY);
    wxString  text = wxT("'Cause sometimes you feel tired,\n\
  feel weak, and when you feel weak,\
  you feel like you wanna just give up.\n\
  But you gotta search within you,\
  you gotta find that inner strength\n\
  and just pull that shit out of you\
  and get that motivation to not give up\n\
  and not be a quitter,\
  no matter how bad you wanna just fall flat on your face and collapse.");
 
 
    wxStaticText *st = new wxStaticText(panel, wxID_ANY, text, 
        wxPoint(10, 10), wxDefaultSize, wxALIGN_CENTRE);
 
    this->SetSize(600, 110);
    this->Centre();
}
main.h
#include <wx/wx.h>
 
class MyApp : public wxApp
{
    public:
      virtual bool OnInit();
};
main.cpp
#include "main.h"
#include "statictext.h"
 
IMPLEMENT_APP(MyApp)
 
bool MyApp::OnInit()
{
 
    StaticText *st = new StaticText(wxT("StaticText"));
    st->Show(true);
 
    return true;
}

A példánkban, az Eminem Till I Collapse dalszövegének egy részét jelenítjük meg.

wxStaticText *st = new wxStaticText(panel, wxID_ANY, text, 
      wxPoint(10, 10), wxDefaultSize, wxALIGN_CENTRE);

Itt készítünk egy wxStaticText widgetet. A statikus szöveg középre van igazítva.

wxSlider

A wxSlider egy fogantyúval rendelkező widget. A fogantyú oda-vissza húzható. Így választhatunk egy értéket, valamilyen feladathoz. A csúszka használata néha természetesebb, mint egy számokat megadni, vagy léptetődobozt használni.

Slider.h
#include <wx/wx.h>
#include <wx/slider.h>
 
class MyPanel : public wxPanel
{
public:
      MyPanel(wxFrame *parent);
 
      void OnPaint(wxPaintEvent& event);
      void OnScroll(wxScrollEvent& event);
 
      wxSlider *slider;
      int fill;
 
};
 
class Slider : public wxFrame
{
public:
      Slider(const wxString& title);
 
      MyPanel *panel;
 
};
 
const int ID_SLIDER = 100;
Slider.cpp
#include "Slider.h"
 
Slider::Slider(const wxString& title)
         : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, 
         wxSize(270, 200))
{
    panel = new MyPanel(this);
    Center();
}
 
 
MyPanel::MyPanel(wxFrame * parent)
         : wxPanel(parent, wxID_ANY)
{
    fill = 0;
    slider = new wxSlider(this, ID_SLIDER, 0, 0, 140, wxPoint(50, 30), 
        wxSize(-1, 140), wxSL_VERTICAL);
 
    Connect(ID_SLIDER, wxEVT_COMMAND_SLIDER_UPDATED, 
      wxScrollEventHandler(MyPanel::OnScroll));  
    Connect(wxEVT_PAINT, wxPaintEventHandler(MyPanel::OnPaint));
 
}
 
void MyPanel::OnScroll(wxScrollEvent& event)
{
    fill = slider->GetValue();
    Refresh();
}
 
void MyPanel::OnPaint(wxPaintEvent& event)
{
    wxPaintDC dc(this);
 
    wxPen pen(wxColour(212, 212, 212));
    dc.SetPen(pen);
 
    dc.DrawRectangle(wxRect(140, 30, 80, 140));  
 
    wxBrush brush1(wxColour(197, 108, 0));
    dc.SetBrush(brush1);
 
    dc.DrawRectangle(wxRect(140, 30, 80, fill));
}
main.h
#include <wx/wx.h>
 
class MyApp : public wxApp
{
  public:
      virtual bool OnInit();
};
main.cpp
#include "main.h"
#include "Slider.h"
 
IMPLEMENT_APP(MyApp)
 
bool MyApp::OnInit()
{
 
    Slider *slider = new Slider(wxT("Slider"));
    slider->Show(true);
 
    return true;
}
 
 
A példánkban, megmutatjauk a slider widget használatát. A csúszka fogantyúját húzva, beállíthatjuk
a panel háttérszínét. Ebben a példában is természetesebb a slider használata, mint például egy
léptetődoboz. 
 
 
 
<code cpp>
  slider = new wxSlider(this, ID_SLIDER, 0, 0, 140, wxPoint(50, 30), 
     wxSize(-1, 140), wxSL_VERTICAL);

Készítünk egy függőleges slider-t. Kezdőértéke 0, minimumértéke 0, maximumértéke 140. Nincs pipa és felirat.

Connect(ID_SLIDER, wxEVT_COMMAND_SLIDER_UPDATED, 
   wxScrollEventHandler(MyPanel::OnScroll));  

A wxEVT_COMMAND_SLIDER_UPDATED eseménynél, a felhasználó által készített OnScroll() függvényhez kapcsolódunk.

Connect(wxEVT_PAINT, wxPaintEventHandler(MyPanel::OnPaint));

Rajzolni is fogunk, így kapcsolódunk az OnPaint() függvényhez, wxEVT_PAINT esemény esetén.

  fill = slider->GetValue();
  Refresh();

Az OnScroll() metódusban, megkapjuk a slider aktuális értékét. Meghívjuk a Refresh() függvényt, amely wxEVT_PAINT eseményt generál.

dc.DrawRectangle(wxRect(140, 30, 80, 140)); 
...
dc.DrawRectangle(wxRect(140, 30, 80, fill));

Az OnPaint() eseménykezelőn belül, négyzetet rajzolunk. Az első függvény egy fehér téglalapot rajzol, szürke szegéllyel. A második függvény a téglalapot, valamilyen barnás színnel tölti ki. A téglalap magasságát a kitöltési érték határozza meg, ami slider widgettel van bállítva.