Уроки wxSmith: Создание элементов с произвольным отображением и управлением мышью

Материал из Викиучебника — открытых книг для открытого мира

Английский оригинал wiki текста доступен по ссылке. Автор первоначального текста: BYO на codeblocks.org [1]

Предупреждение: не закончено![править]

С возвращением :) Мы уже изучили изящные методы работы с wxSmith в предыдущих уроках и теперь пришло время для чего нибудь поинтереснее. Обычно при написании некоторых наиболее продвинутых приложений оказывается, что ни один из элементов, предоставляемых wxWidgets не подходит для выполнения задачи, особенно, когда нужно представить некоторые данные в графической форме. Как и большинство наборов GUI-компонентов, wxWidgets тоже подготовилась к этому и дает возможность создания элемента с пользовательской прорисовкой и обработки мыши - это позволяет создать любой элемент, какой заблагорассудится.

Создание элемента с пользовательской процедурой прорисовки[править]

Прежде чем начать создание нашего пользовательского элемента, необходимы некоторые знания. Первое, что нужно знать - как wxWidgets рисует элементы.

Большинство элементов имеют пользовательские процедуры прорисовки, предоставляемые операционной системой или некоторый другой инструментарий, доступный в системе (вроде gtk+). В случае таких элементов, когда операционная система отправляет запрос перерисовки элемента, это сообщение пересылается wxWidgets обратно в систему, либо даже вся процедура выполняется без какого-либо вмешательства wxWidgets. К сожалению, это означает, что мы не можем заменить процедуру прорисовки для большинства элементов, и даже если она будет работать на некоторых платформах, то не будет на других. Из элементов, доступных в wxSmith, только wxPanel гарантированно работает с пользовательской процедурой прорисовки.

Теперь, если мы перезапишем прорисовку на wxPanel, wxWidgets будет размещать два события при каждом запросе перерисовки:

* erase background event (EVT_ERASE_BACKGROUND)
* paint event (EVT_PAINT)

Первое используется для подготовки зоны, занятой элементом до добавления контента, а второе - для выполнения текущих графических построений. Мы не обязаны переопределять оба события, так что мы можем нарисовать только произвольный фон или только пользовательское содержимое, оставляя фон по умолчанию.


Вторая вещь, которую нужно знать прежде чем писать пользовательский метод прорисовки - это то, что wxWidgets использует объект для графических построений wxDC. В случае события erase background event этот объект предусмотрен в рамках события; в случае события paint event требуется создать этот объект вручную. Чтобы получить больше информации о wxDC и графических функциях, загляните на эту страницу в документации wxWidgets.

Создание простого ресурса и переопределение метода прорисовки[править]

Теперь давайте создадим самое обычное окно. Для наших целей нам потребуется элемент wxPanel внутри окна с которым мы будем работать:

Теперь давайте вернемся к вкладке событий в обозревателе свойств. Вы можете убедиться, что wxPanel может обрабатывать намного больше событий, чем другие элементы. Это связано с тем, что он может быть использован, как основа для пользовательских элементов, которые могут иметь пользовательский обработчик некоторых стандартных событий. Окей, давайте найдем метод EVT_PAINT (он должен быть в верхней части) и добавим новое пустое событие.

Первое, что мы должны сделать внутри обработчика - необходимо создать объект wxDC, который мы будем использовать. Если взглянуть в документацию wxWidgets, то можно прочесть, что не следует делать того, что вызывает вхождение wxWidgets в бесконечный цикл, потому что метод прорисовки в этом случае будет вызываться снова и снова.

Есть несколько типов объектов wxDC, которые мы могли бы здесь использовать. Наиболее часто используемый - wxPaintDC:

void Tutorial7Dialog::OnPanel1Paint(wxPaintEvent& event)
{
    wxPaintDC dc( Panel1 );
}

Можете заметить, что указатель панели стоит в качестве аргумента, wxPaintDC требуется в его конструкторе указатель на элемент, на котором будут производиться графические построения. Запомните: использовать указатель this не нужно.

Теперь давайте добавим немного кода прорисовки - всего лишь диагональную линию, чтобы протестировать, что прорисовка работает.

void Tutorial7Dialog::OnPanel1Paint(wxPaintEvent& event)
{
    wxPaintDC dc( Panel1 );
    dc.DrawLine( 0, 0, 100, 100 );
}

Теперь, если запустить приложение, окно будет выглядеть так:


Предыдущий | Оглавление | Следующий

Ссылки[править]

  1. Code::Blocks wiki: WxSmith tutorial: Creating items with custom paint and mouse handling