Glade を使って、gtk3 で図形を描画します。(Gtk::DrawingArea,Cairo::Contex)
図形を描画するには、まず描画領域(DrawingArea)を配置し、その中で画像描画ライブラリcairo を使って図形を描画します。
・glade_drawing_1.rb

ウィンドウを広げると、2倍の大きさに表示されているのが分かります。

3.応用
描画領域(DrawingArea)の上にテキストビュー(TextView)を重ねて表示してみます。

・glade_drawing_2.ui
・glade_drawing_2.rb
図形を描画するには、まず描画領域(DrawingArea)を配置し、その中で画像描画ライブラリcairo を使って図形を描画します。
参考)
→・GTK+ CSS - GTK+ 3 Reference Manual
→・PyCairo tutorial - ZetCode
1.描画領域(DrawingArea)の配置
Glade を起動し、ウィンドウ(GtkWindow)を作り、位置指定(GtkFixed)コンテナなどを置き、その上に描画領域をドラッグします。
(Glade の左列>「コントロールと表示」>「描画領域」にあります)
○大きさ
右下の「描画領域のプロパティ」>「共通」;
・要求する幅
○位置
右下の「描画領域のプロパティ」>「パッキング」;
・X位置
・Y位置
○シグナル
右下の「描画領域のプロパティ」>「シグナル」>「draw」
を選びます。
2.描画する(Cairo::Context を使う)
(※ 注意;
macOS の Retina Display や 他OS の 高解像度(HiDPI)ディスプレイには、大元の gtk+3(version 3.22.26)ライブラリがまだ対応していません。そのため、macOS の Retina Display では、ウィンドウ自体が2倍の大きさに描画されてしまいます。
→・HiDPI/Retina display support and gtk3-port branch? (2014) — GIMP Development — gimpusers.com )
(2018.11.1 追記;
Ruby/GTK3 がバージョンアップして、高解像度ディスプレイでも2倍にならずに描画するようになりました。gtk3 3.3.0)
Ruby側のプログラムで、描画ライブラリの Cairo::Context を使って描画します。
なお、描画領域(DrawingArea)で設定した drawシグナルは、自動的に第2引数に Cairo::Contex を生成してくれます(第1引数は DrawingArea自身)。
そのため、改めて Cairo::Contex を生成する必要はありません。
描画するには、drawシグナルを受け取るメソッドの中で以下に挙げた描画処理を記述します。
○大きさ
右下の「描画領域のプロパティ」>「共通」;
・要求する幅
・要求する高さ
○位置
右下の「描画領域のプロパティ」>「パッキング」;
・X位置
・Y位置
○シグナル
右下の「描画領域のプロパティ」>「シグナル」>「draw」
を選びます。
2.描画する(Cairo::Context を使う)
(※ 注意;
macOS の Retina Display や 他OS の 高解像度(HiDPI)ディスプレイには、大元の gtk+3(version 3.22.26)ライブラリがまだ対応していません。そのため、macOS の Retina Display では、ウィンドウ自体が2倍の大きさに描画されてしまいます。
→・HiDPI/Retina display support and gtk3-port branch? (2014) — GIMP Development — gimpusers.com )
(2018.11.1 追記;
Ruby/GTK3 がバージョンアップして、高解像度ディスプレイでも2倍にならずに描画するようになりました。gtk3 3.3.0)
Ruby側のプログラムで、描画ライブラリの Cairo::Context を使って描画します。
なお、描画領域(DrawingArea)で設定した drawシグナルは、自動的に第2引数に Cairo::Contex を生成してくれます(第1引数は DrawingArea自身)。
そのため、改めて Cairo::Contex を生成する必要はありません。
描画するには、drawシグナルを受け取るメソッドの中で以下に挙げた描画処理を記述します。
色の設定をする
・red, green, blue (, alpha);0-1.0
○Cairo::Context#set_line_width(width)
線の太さを設定する(1.0 が標準)
座標の拡大率を設定する(1.0で等倍)
点を打つ座標を指定する
前の座標から(x, y)までの直線を引く(経路を)指定をする
指定された経路を線で描く
○Cairo::Context#rectangle(x1, y1, x2, y2)
四角を描く
円弧を描く
・中心;x, y
・半径;radius
・描画開始点;starting_point(角度;ラジアン 0 〜 2*Math::PI)
・描画終了点;ending_point
図形内部に色を塗る
○Cairo::Context#destroy
Cairo::Context を廃棄します
(描画処理の最後に使うことがあるようですが、エラーが出なければ特に使う必要はないようです)
(描画処理の最後に使うことがあるようですが、エラーが出なければ特に使う必要はないようです)
設定例;
<?xml version="1.0" encoding="UTF-8"?><!-- Generated with glade 3.20.0 --><interface><requires lib="gtk+" version="3.20"/><object class="GtkWindow" id="window_1"><property name="can_focus">False</property><property name="default_width">400</property><property name="default_height">300</property><signal name="destroy" handler="gtk_main_quit" swapped="no"/><child><object class="GtkFixed"><property name="visible">True</property><property name="can_focus">False</property><child><object class="GtkDrawingArea" id="drawingarea1"><property name="width_request">290</property><property name="height_request">160</property><property name="visible">True</property><property name="can_focus">False</property><signal name="draw" handler="on_drawingarea1_draw" swapped="no"/></object><packing><property name="x">20</property><property name="y">20</property></packing></child></object></child></object></interface>
・glade_drawing_1.rb
require 'gtk3'builder = Gtk::Builder.newbuilder.add_from_file("glade_drawing_1.ui")win = builder.get_object("window_1")def gtk_main_quitGtk.main_quitenddef on_drawingarea1_draw(widget, cairo_contex) #drawシグナルは、第2引数にCairo::Contexが入るcairo_contex.set_source_rgb(0, 1.0, 1.0) # RGB; 0-1.0cairo_contex.paintcairo_contex.set_source_rgb(1.0, 0, 0)cairo_contex.set_line_width(1)cairo_contex.move_to( 0, 10)cairo_contex.line_to( 25, 10)cairo_contex.line_to( 37, 0)cairo_contex.line_to( 49, 10)cairo_contex.line_to(289, 10)cairo_contex.line_to(289, 159)cairo_contex.line_to( 0, 159)cairo_contex.line_to( 0, 10)cairo_contex.strokecairo_contex.set_source_rgb(1.0, 0, 1.0)cairo_contex.arc(20, 40, 10, 0, 2 * Math::PI)cairo_contex.fillendbuilder.connect_signals {|handler| method(handler)}win.show_allGtk.main
(2018.11.1 追記;
gtk3 3.3.0 で正常に表示するようになりました)
gtk3 3.3.0 で正常に表示するようになりました)

ウィンドウを広げると、2倍の大きさに表示されているのが分かります。

3.応用
描画領域(DrawingArea)の上にテキストビュー(TextView)を重ねて表示してみます。
設定例;
○ウィンドウ(GtkWindow)
・ID:window_1
・デフォルトの幅:400
・デフォルトの高さ:300
・シグナル:destroy,ハンドラーの名前:gtk_main_quit
○位置指定(GtkFixed)
デフォルトのまま
○描画領域(DrawingArea)
・ID:drawingarea1
・パッキング:X位置: 20,Y位置: 20
・共通:要求する幅: 290,要求する高さ: 160
・シグナル:draw,ハンドラーの名前:on_drawingarea1_draw
○テキストビュー(GtkTextView)
・ID:textview1
・ID:textbuffer1
・ラベル:Hello World!
○テキストビュー(GtkTextView)
・ID:textview1
・パッキング:X位置: 80,Y位置: 80
・共通:要求する幅: 150,要求する高さ: 50
・バッファー:textbuffer
○テキストバッファー(GtkTextBuffer)・共通:要求する幅: 150,要求する高さ: 50
・バッファー:textbuffer
・ID:textbuffer1
・ラベル:Hello World!

・glade_drawing_2.ui
<?xml version="1.0" encoding="UTF-8"?><!-- Generated with glade 3.20.0 --><interface><requires lib="gtk+" version="3.20"/><object class="GtkTextBuffer" id="textbuffer1"><property name="text">Hello World!</property></object><object class="GtkWindow" id="window_1"><property name="can_focus">False</property><property name="default_width">400</property><property name="default_height">300</property><signal name="destroy" handler="gtk_main_quit" swapped="no"/><child><object class="GtkFixed"><property name="visible">True</property><property name="can_focus">False</property><child><object class="GtkDrawingArea" id="drawingarea1"><property name="width_request">290</property><property name="height_request">160</property><property name="visible">True</property><property name="can_focus">False</property><signal name="draw" handler="on_drawingarea1_draw" swapped="no"/></object><packing><property name="x">20</property><property name="y">20</property></packing></child><child><object class="GtkTextView" id="textview1"><property name="width_request">150</property><property name="height_request">50</property><property name="visible">True</property><property name="can_focus">True</property><property name="buffer">textbuffer1</property></object><packing><property name="x">80</property><property name="y">80</property></packing></child></object></child></object></interface>
・glade_drawing_2.rb
require 'gtk3'builder = Gtk::Builder.newbuilder.add_from_file("glade_drawing_2.ui")win = builder.get_object("window_1")def gtk_main_quitGtk.main_quitenddef on_drawingarea1_draw(widget, cairo_contex) #drawシグナルは、第2引数にCairo::Contexが入るcairo_contex.set_source_rgb(0, 1.0, 1.0) # RGB; 0-1.0cairo_contex.paintcairo_contex.set_source_rgb(1.0, 0, 0)cairo_contex.set_line_width(1)cairo_contex.move_to( 0, 10)cairo_contex.line_to( 25, 10)cairo_contex.line_to( 37, 0)cairo_contex.line_to( 49, 10)cairo_contex.line_to(289, 10)cairo_contex.line_to(289, 159)cairo_contex.line_to( 0, 159)cairo_contex.line_to( 0, 10)cairo_contex.strokecairo_contex.set_source_rgb(1.0, 0, 1.0)cairo_contex.arc(20, 40, 10, 0, 2 * Math::PI)cairo_contex.fillendtext_area = builder.get_object("textview1")css_provider = Gtk::CssProvider.newcss_provider.load(data:"text {background-color: yellow;}")text_area.style_context.add_provider(css_provider, Gtk::StyleProvider::PRIORITY_USER)builder.connect_signals {|handler| method(handler)}win.show_allGtk.main