Как я могу контролировать, когда код выполняется в событии on_draw gktmm3-Gtk :: DrawingArea

Я использую C ++ 11 с цепочкой инструментов GNU с gtkmm3, на Ubuntu 12.04 LTS 32 bit.
Я экспериментировал с некоторыми примерами для gtkmm3 в Программирование с помощью gtkmm 3.

На основе 17.2.1.Example там я унаследовал от Gtk::DrawingArea (MyDrawingArea здесь) и преодолеть on_draw() Обработчик событий выглядит следующим образом:

MyDrawingArea.hpp

...

protected:

bool on_draw ( const Cairo::RefPtr<Cairo::Context>& cr ) override;

MyDrawingArea.cpp (быстро и грязно, просто для демонстрации концепции)

double y{ 10 };
double x{ 10 };

bool MyDrawingArea::on_draw( const Cairo::RefPtr<Cairo::Context>& cr )
{
this->get_window( )->freeze_updates( );
cr->set_line_width( 3.0 );
cr->set_source_rgb( 1, 0, 0 );
cr->move_to( x, y );
cr->line_to( x * 2, y * 2 );
cr->stroke( );
this->get_window( )->thaw_updates( );
x += 50;
y += 50;
return true;
}

Этот код рисует одну диагональную линию. Я хочу, чтобы его позиция изменилась, когда я звонюMyDrawingArea.queue_draw() через обработчик событий в моем приложении. Это работает:

Событие 1:
введите описание изображения здесь
Событие 2:
введите описание изображения здесь

Моя проблема в том, что, очевидно, on_draw() обработчик событий срабатывает каждый раз, когда окно перерисовывается. Просто перемещая главное окно приложения (которое содержит MyDrawingArea) причины on_draw() стрелять и линия отображается в новой позиции.

Как я могу контролировать, когда код в моем on_draw() событие будет запущено, так что линия отображается заново только тогда, когда я звоню MyDrawingArea.queue_draw() в моем коде приложения, но сохраняется в прежнем состоянии в другое время? (Я не считать Я спрашиваю о том, как предотвратить on_draw() от стрельбы, но, может быть, это то, что должно произойти?)

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

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

Как мне это сделать? Нужна ли логика для управления двумя разными on_draw() Параметры: Если приложение выполняет вызов, отобразить новую версию строки, если нет, перекрасить старую версию? Это становится сложным — я думаю, что что-то упустил. Есть ли другое событие, которое я должен использовать? Это какой-то способ, которым я могу получить от Cairo::Context информация о том, кто звонил On_draw()и т. д., что поможет мне решить эту проблему?

1

Решение

Если вы намереваетесь вызвать / отключить Gtk.DrawingArea с помощью кнопки переключения, просто спросите, активна ли кнопка переключения или нет, чем перерисовать область.

<!------ language python ------>
def on_draw (self, widget):
# your cairo draw here
......
......
if toggle_button.get_active () is True: #toggle to show DrawingArea
x+=50
y+=50
# other than that it simply sits there doing nothing

Теперь о отключении сигнала «рисовать». Поместите последнюю копию рендеринга cr где-нибудь в буфер, и когда вы будете готовы запустить его снова, подключитесь снова, но на этот раз не получите cairo * cr из параметра сигнала «рисовать». Используйте копию

2

Другие решения

Я решил эту проблему, написав небольшой конечный автомат, который контролирует, как on_draw() Событие ведет себя:

Перечисление, представляющее различные состояния сигнала при включении on_draw() пожары:

enum class Draw_Signals
{
DS_RedrawSignal, DS_HoldSignal, DS_ClearSignal, DS_End
};

DS_RedrawSignal

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

DS_HoldSignal

Средства поддерживают текущее графическое состояние, но ничего нового не делают.

DS_ClearSignal

Означает полностью очистить область рисования и начать все сначала.

MyDrawingArea класс имеет член:

Draw_Signals mDSignal { Draw_Signals::DS_HoldSignal };

Это значение устанавливается методами, которые вызываютon_draw() из моего приложения с помощью метода «сеттер».

Не вдаваясь во все детали, мой MyDrawingArea::on_draw() теперь выглядит примерно так:

bool MyDrawingArea::on_draw( const Cairo::RefPtr<Cairo::Context>& cr )
{

get_window( )->freeze_updates( );

switch ( mDSignal )
{
case Draw_Signals::DS_RedrawSignal:
{
DrawNewLine( cr );//draws new line and caches it for use when RedrawOldLine() is called.
break;
}

case Draw_Signals::DS_HoldSignal:
{
RedrawOldLine( cr );
break;
}

case Draw_Signals::DS_ClearSignal:
{
clearDrawArea( );
}

}

get_window( )->thaw_updates( );

mDSignal = Draw_Signals::DS_HoldSignal;

return true;

}

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

1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector