Я использую С++ 11 с цепочкой инструментов GNU с gtkmm3 на Ubuntu 12.04 LTS 32 бит. Я играл с некоторыми примерами для gtkmm3 в Программирование с помощью gtkmm 3а>.
На основе 17.2.1.Пример здесь я унаследовал от Gtk::DrawingArea
(здесь MyDrawingArea
) и переопределил обработчик событий on_draw()
следующим образом:
MyDrawingArea.hpp
...
protected:
bool on_draw ( const Cairo::RefPtr<Cairo::Context>& cr ) override;
MyDrawingArea.cpp
bool MyDrawingArea::on_draw( const Cairo::RefPtr<Cairo::Context>& cr )
{
Gtk::Allocation allocation = get_allocation( );
const int width = allocation.get_width( );
const int height = allocation.get_height( );
int coord1{ height - 3 };
cr->set_line_width( 3.0 );
this->get_window( )->freeze_updates( );
cr->set_source_rgb( 0, 0.40, 0.60 );
cr->move_to( 0, coord1 );
cr->line_to( width, coord1 );
cr->stroke( );
cr->set_source_rgb( 1, 0.05, 1 );
cr->move_to( mXStart, coord1 );
cr->line_to( mXStart, mYAxis * 1.5 );
cr->show_text( to_string( mYAxis ) );
cr->stroke( );
mXStart += 5;
this->get_window( )->thaw_updates( );
return true;
}
Моя цель — нарисовать простую гистограмму на основе вычислений, которые я делаю в небольшом тестовом приложении. Идея состоит в том, что каждый раз, когда вызывается событие on_draw()
, следующая полоса будет перемещаться на 5 единиц вправо по mXAxis
и вертикальной линии. будет нарисовано на основе нового значения mYaxis
, которое вычисляется на основе результатов нового вычисления.
Когда я хочу перерисовать свой график и вызвать событие MyDrawingArea::on_draw(), я вызываю MyDrawingArea.show_all() из своего приложения после завершения вычислений и установки новых осей x и y.
Однако это не работает так, как я ожидал: MyDrawingArea.show_all()
делает недействительным все окно рисования и рисует с нуля: новая линия графика появляется на своем месте, но предыдущие стираются. Я также пробовал MyDrawingArea.queue_draw()
, который имел тот же эффект. Но я хочу сохранить предыдущие результаты графика, чтобы иметь возможность получить профиль результатов вычислений, так как я вычисляю с другими значениями.
Эта реализация также приводит к тому, что нижняя линия на моем графике (моя ось x на графике), нарисованная первым вызовом stroke()
в моем примере кода, отображается заново при каждом вызове on_draw() - хотя это не должно быть обязательным, поскольку эта строка сохраняется в течение всего времени существования MyDrawingArea
- нет необходимости делать ее недействительной, а затем перерисовывать ее при каждом новом событии on_draw()
, как это делает мой код в настоящее время, потому что я еще не нашел способ справиться с этим.
Я очень новичок в Каире, поэтому я уверен, что, вероятно, делаю это совершенно неправильно, но явная, ориентированная на задачи документация кажется скудной - не нашел ничего, что объясняло бы, как это сделать, хотя я уверен, что это довольно просто.
Что мне нужно сделать, чтобы нарисовать новую линию на Gtk::DrawingArea
, сохраняя при этом предыдущие линии графика, которые уже были нарисованы на предыдущих проходах, и установить графические элементы, которые будут сохраняться в течение всего времени существования виджета Gtk::DrawingArea
. Очевидно, что использовать show_all()
или queue_draw()
и делать все это в событии on_draw()
— не лучший вариант.