Sl-Alex домашняя лаборатория

Руководство по WxWidgets: 2. Первые программы

Просмотров: 3878Комментарии: 0
Статьи
Руководство по WxWidgets: 2. Первые программы

В этой главе мы опишем основы, необходимые для создания wxWidgets приложений. Мы создадим наш первый пример, показывающий как отобразить иконку. Далее мы создадим пример демонстрирующий работу с событиями. И в заключении мы увидим как взаимодействуют виджеты внутри wxWidgets приложений.

В конце главы, как водится, ссылки на остальные материалы курса.

Простое приложение

Для начала создадим очень простую wxWidgets программу.

simple.h:
#include <wx/wx.h>
class Simple : public wxFrame
{
	public:
		Simple(const wxString& title);
};
simple.cpp:
#include "simple.h"
Simple::Simple(const wxString& title)
	: wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(250, 150))
{
	Centre();
}
main.h:
#include <wx/wx.h>
class MyApp : public wxApp
{
	public:
		virtual bool OnInit();
};
main.cpp:
#include "main.h"
#include "simple.h"
IMPLEMENT_APP(MyApp)
bool MyApp::OnInit()
{
	Simple *simple = new Simple(wxT("Simple"));
	simple->Show(true);
	return true;
}

Этот очень простой пример выводит небольшое окно с заголовком Simple в центре экрана.

Centre();

Этот метод центрует окно на экране по горизонтали и вертикали.

IMPLEMENT_APP(MyApp)

Этот макрос реализует функцию main() в приложениях wxWidgets, скрывая подробности главного цикла ожидания события. Это код для подстановки (вставки) и обычно нам не нужно об этом сильно беспокоится.

Для компиляции программы используйте следующие команды (Unix/Linux):

g++ main.cpp main.h simple.cpp simple.h `wx-config --cxxflags --libs` -o simple

Рисунок 2.1: Простое приложение

Рисунок 2.1: Простое приложение

Вывод иконки приложения

В этом примере мы снабдим нашу программу иконкой. Т.к. стало стандартом отображать небольшую иконку в верхнем левом углу окна. Эта иконка является графическим идентификатором программы.

icon.h:
#include <wx/wx.h>
class Icon : public wxFrame
{
	public:
		Icon(const wxString& title);
};
icon.cpp:
#include "icon.h"
Icon::Icon(const wxString& title)
	: wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(250, 150))
{
	SetIcon(wxIcon(wxT("web.xpm")));
	Centre();
}
main.h:
#include <wx/wx.h>
class MyApp : public wxApp
{
	public:
		virtual bool OnInit();
};
main.cpp:
#include "main.h"
#include "icon.h"
IMPLEMENT_APP(MyApp)
bool MyApp::OnInit()
{
	Icon *icon = new Icon(wxT("Icon"));
	icon->Show(true);
	return true;
}

В нашей программе будет использована маленькая веб иконка.

SetIcon(wxIcon(wxT("web.xpm")));

Отображение иконки осуществляется этой строкой. XPM (X PixMap) графический ASCII формат.

Рисунок 2.2: Иконка

Рисунок 2.2: Иконка

Простая кнопка

В следующем примере мы создадим кнопку в рамке виджета. А так же покажем как создать простой обработчик событий.

button.h:
#include <wx/wx.h>
class Button : public wxFrame
{
	public:
		Button(const wxString& title);
	
		void OnQuit(wxCommandEvent & event);
};
button.cpp:
#include "button.h"
Button::Button(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));
	Connect(wxID_EXIT, wxEVT_COMMAND_BUTTON_CLICKED, 
		wxCommandEventHandler(Button::OnQuit));
	button->SetFocus();
	
	Centre();
}
void Button::OnQuit(wxCommandEvent & WXUNUSED(event))
{
	Close(true);
}
main.h:
#include <wx/wx.h>
class MyApp : public wxApp
{
	public:
		virtual bool OnInit();
};
main.cpp:
#include "main.h"
#include "button.h"
IMPLEMENT_APP(MyApp)
bool MyApp::OnInit()
{
	Button *btnapp = new Button(wxT("Button"));
	btnapp->Show(true);
	
	return true;
}
wxPanel *panel = new wxPanel(this, wxID_ANY);

Сначала мы создаём панель wxPanel. Она должен быть помещена внутри окна wxFrame.

wxButton *button = new wxButton(panel, wxID_EXIT, wxT("Quit"), wxPoint(20, 20));

Теперь создаём кнопку wxButton. Она располагается на панели. Мы используем предопределённый wxID_EXIT id для кнопки. Благодаря чему на кнопке отображается небольшая exit иконка. Метка кнопки - "Quit". Кнопка позиционируется вручную координатами (x=20, y=20). Начало системы координат в верхнем левом углу.

Connect(wxID_EXIT, wxEVT_COMMAND_BUTTON_CLICKED,
	wxCommandEventHandler(Button::OnQuit));

Если мы нажимаем на кнопку то генерируется событие wxEVT_COMMAND_BUTTON_CLICKED. Мы связываем это событие с методом OnQuit() класса Button. Следовательно, когда мы нажимаем на кнопку, вызывается метод OnQuit().

button->SetFocus();

Устанавливаем фокус клавиатуры (фокус ввода) на кнопке. В результате нажатие клавиши Enter приведёт к нажатию кнопки.

Close(true);

Внутри метода OnQuit() мы вызываем метод Close(), который прекращает работу программы.

Рисунок 2.3: Кнопка

Рисунок 2.3: Кнопка

Взаимодействие виджетов

Очень важно знать как виджеты могут взаимодействовать в приложении. Рассмотрим следующий пример:

Panels.h:
#include <wx/wx.h>
#include <wx/panel.h>
class LeftPanel : public wxPanel
{
public:
    LeftPanel(wxPanel *parent);
    void OnPlus(wxCommandEvent & event);
    void OnMinus(wxCommandEvent & event);
    wxButton *m_plus;
    wxButton *m_minus;
    wxPanel *m_parent;
    int count;
};
class RightPanel : public wxPanel
{
public:
    RightPanel(wxPanel *parent);
    void OnSetText(wxCommandEvent & event);
    wxStaticText *m_text;
};
const int ID_PLUS = 101;
const int ID_MINUS = 102;
Panels.cpp:
#include <wx/stattext.h>
#include "Communicate.h"
LeftPanel::LeftPanel(wxPanel * parent)
       : wxPanel(parent, -1, wxPoint(-1, -1), wxSize(-1, -1), wxBORDER_SUNKEN)
{
  count = 0;
  m_parent = parent;
  m_plus = new wxButton(this, ID_PLUS, wxT("+"), 
      wxPoint(10, 10));
  m_minus = new wxButton(this, ID_MINUS, wxT("-"), 
      wxPoint(10, 60));
  Connect(ID_PLUS, wxEVT_COMMAND_BUTTON_CLICKED, 
      wxCommandEventHandler(LeftPanel::OnPlus));
  Connect(ID_MINUS, wxEVT_COMMAND_BUTTON_CLICKED, 
      wxCommandEventHandler(LeftPanel::OnMinus));
}
void LeftPanel::OnPlus(wxCommandEvent & WXUNUSED(event))
{
  count++;
  Communicate *comm = (Communicate *) m_parent->GetParent();
  comm->m_rp->m_text->SetLabel(wxString::Format(wxT("%d"), count));
}
void LeftPanel::OnMinus(wxCommandEvent & WXUNUSED(event))
{
  count--;
  Communicate *comm = (Communicate *) m_parent->GetParent();
  comm->m_rp->m_text->SetLabel(wxString::Format(wxT("%d"), count));
}
RightPanel::RightPanel(wxPanel * parent)
       : wxPanel(parent, wxID_ANY, wxDefaultPosition, 
         wxSize(270, 150), wxBORDER_SUNKEN)
{
    m_text = new wxStaticText(this, -1, wxT("0"), wxPoint(40, 60));
}
Communicate.h:
#include "Panels.h"
#include <wx/wxprec.h>
class Communicate : public wxFrame
{
public:
    Communicate(const wxString& title);
    LeftPanel *m_lp;
    RightPanel *m_rp;
    wxPanel *m_parent;
};
Communicate.cpp:
#include "Communicate.h"
Communicate::Communicate(const wxString& title)
       : wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(290, 150))
{
  m_parent = new wxPanel(this, wxID_ANY);
  wxBoxSizer *hbox = new wxBoxSizer(wxHORIZONTAL);
  m_lp = new LeftPanel(m_parent);
  m_rp = new RightPanel(m_parent);
  hbox->Add(m_lp, 1, wxEXPAND | wxALL, 5);
  hbox->Add(m_rp, 1, wxEXPAND | wxALL, 5);
  m_parent->SetSizer(hbox);
  this->Centre();
}
main.h:
#include <wx/wx.h>
class MyApp : public wxApp
{
  public:
    virtual bool OnInit();
};
main.cpp:
#include "main.h"
#include "Communicate.h"
IMPLEMENT_APP(MyApp)
bool MyApp::OnInit()
{
    Communicate *communicate = new Communicate(wxT("Widgets communicate"));
    communicate->Show(true);
    return true;
}

В нашем примере создано 2 панели (левая и правая). Левая содержит 2 кнопки, правая - статический текст. Кнопки меняют числовое значение, отображаемое в статическом тексте. Вопрос в том как мы получаем указатель на статический текст.

m_parent = parent;

Здесь мы сохраняем указатель на родительский виджет левой панели. Это виджет wxPanel.

Communicate *comm = (Communicate *) m_parent->GetParent();
comm->m_rp->m_text->SetLabel(wxString::Format(wxT("%d"), count));

Эти 2 строчки наиболее важные в примере. Как показано, мы получаем доступ к виджету статического текста, находящегося на другой панели. Сначала мы получаем указатель на родительский виджет обоих панелей, а он, в свою очередь содержит указатель на правую панель, а она - указатель на статический текст.

Рисунок 2.4: Взаимодействие виджетов

Рисунок 2.4: Взаимодействие виджетов

Остальные материалы курса:

Вступление

1. Вспомогательные классы

2. Первые программы

3. Меню и панели инструментов

4. Управление компоновкой

5. События

6. Диалоги

7. Виджеты часть 1

8. Виджеты часть 2

9. Перетаскивание

10. Контексты устройств

11. Самодельные виджеты

12. Тетрис в wxWidgets

Примечание

Оригинал руководства расположен здесь. Автор оригинала - Jan Bodnar.

Перевод (без разметки и картинок) был выполнен пользователем ber113 с сайта translated.by. К сожалению, сайт сейчас не работает.

Данный документ представляет собой компиляцию указанных документов с сохранением оригинальной разметки и иллюстраций.