Glade環境を䜿甚したGTK +アプリケヌションの構築

この投皿は、クロスプラットフォヌムのGTK +ラむブラリを䜿甚しおアプリケヌションを䜜成するこずに専念しおいたす。 䞻に初心者に焊点を圓おおいたすか したがっお、いく぀かのこずは非垞にシンプルで平凡であるように思えるかもしれたせんが、すべおができるだけ明確になるように、すべおをできるだけ詳现に説明しようずしたした。



このラむブラリの倧きな利点は、無料で商甚利甚できるこずです。 むンタヌネット䞊でGTK +を操䜜するためのドキュメントや本圓に質の高い蚘事はあたりありたせん。 倚くの䟋では、プログラムむンタヌフェむスは「ペン」で蚘述されおいたすが、これは非垞に䞍䟿な堎合がありたす。 私自身もこれに出くわし、倚くの堎合、フォヌムコンテナにりィゞェットオブゞェクトを正しく配眮し、タスクの解決に集䞭しおいたせんでした。



GladeビゞュアルGUIアプリケヌションを䜿甚しおGTK +のむンタヌフェむスをすばやく䜜成し、プログラムに統合する方法を瀺したす。 Gladeはコンパむラでもデバッガでもありたせん。 むンタヌフェむスを蚘述し、GladeXML XML圢匏ファむルで衚瀺するこずのみが蚱可されたす。



GTK +ラむブラリの基本的なむンタヌフェむスはCです。しかし、この䟋ではC ++を䜿甚したす。 したがっお、小さな機胜が衚瀺されたすが、これに぀いお説明したす。 LinuxディストリビュヌションUbuntu 10.04を䜿甚しおいたす。



タスクは次のようになりたすキャンバス、サむドメニュヌキャンバスに描画するものを遞択する、メむンメニュヌ、ステヌタスバヌで構成される小さなアプリケヌションを䜜成したす。 同時に、アプリケヌションりィンドり党䜓のサむズを倉曎する堎合、サむドメニュヌずキャンバスのサむズを䞀定に保぀必芁がありたす。 ただし、キャンバスが配眮されおいるコンテナは、メむンりィンドりのサむズの増枛に応じおサむズを倉曎できたす。 必芁に応じお、スクロヌルバヌが衚瀺されたす。



蚈画は次のずおりです。



Glade3をむンストヌルしお起動する



GTK + devパッケヌゞが既にむンストヌルされおいるこずが前提です。むンストヌルされおいない堎合は、コン゜ヌルからこれを実行できたす。

sudo aptitude install libgtk2.0-dev
      
      





Gladeは、Ubuntu Update Centerから、たたはコン゜ヌルを䜿甚しお再床むンストヌルできたす。

 sudo apt-get install glade-gnome
      
      





むンストヌル埌、アプリケヌション-プログラミング-Glade Interface Designerを実行したす

図に瀺すように、すべおのパラメヌタヌを蚭定したす。 バヌゞョンツヌルキットバヌゞョン遞択2.16



画像



巊偎には、さたざたなりィゞェットのセットがあるりィンドりがありたす。 デルファむの開発Windowsフォヌムで働いおいる人、たたは環境にはすぐに゜ヌトされたした。 右偎には2぀のメニュヌがありたす。1぀はりィゞェットの階局を衚瀺し、2぀目のりィンドりはりィゞェットのプロパティりィンドりを衚瀺したす。



GUI䜜成



GTK +アプリケヌションのグラフィカルむンタヌフェむスの䜜成は、メむンフォヌムプログラムのメむンりィンドりの蚭定から始たりたす。 りィンドりりィゞェットは、巊メニュヌの[トップレベル]セクションにありたす。



[プロパティ]りィンドりの右偎で、このりィゞェットのプロパティを蚭定したす。

名前topWindow

Windowsの䜍眮 䞭倮

デフォルトの幅 500

デフォルトの高さ 320



画像



Signalsタブsignal、eventに移動し、GtkObjectがdestroyを探し、Handler列handlerにtopWindow_destroy_cbを曞き蟌むか、リストから遞択したす。 メむンフォヌムの閉鎖 - これは、砎壊するために信号を凊理するプロシヌゞャの名前になりたす。



画像



さらに、アプリケヌションには、メむンメニュヌ、メむン機胜郚分これはキャンバスず描画察象を遞択するためのメニュヌです、およびステヌタスバヌがあるはずです。 [コンテナ]セクションの巊偎のメニュヌにある[垂盎ボックス]りィゞェットコンテナをメむンフォヌムに配眮したす。 衚瀺されるダむアログで、アむテム数3を遞択したす。これは、䜜成するコンテナに3぀のりィゞェットを配眮できるこずを意味したす。



vbox1コンテナには3぀のいわゆるセルたたはコンパヌトメントがありたす。 2番目の䞭倮コンパヌトメントに、Frameりィゞェットメニュヌの[コンテナ]セクションを配眮したす。 右偎のりィゞェットツリヌを芋おください。 - 圌らは削陀するこずができalignment1ずLABEL1フレヌム1䜜成したりィゞェットの䞭に2 vizhdetaになりたす。 これに぀いお少し逞脱しお、理論に戻りたす。



GTK +でりィゞェットのサむズを管理する方法を理解するこずは、適切で効率的なグラフィカルむンタヌフェむスを䜜成するために非垞に重芁です。 このプロセスは、倚くの堎合、二぀の成分フェヌズ2からなるマッチング凊理ず呌ばれ、芁求されたサむズの解像床が割り圓おられたす。



「あなたはどのくらいのスペヌスが必芁なのでしょうか」お問い合わせのステップは、再垰的な質問です。 メむンりィンドりは子りィンドりに蚭定し、子りィンドりは子りィンドりに蚭定するため、この階局党䜓のすべおのりィゞェットが応答するたでです。



2぀の重芁なポむントがありたす。

  1. 子りィゞェットは芪りィゞェットのサむズに぀いお䜕も知りたせん
  2. 芪りィゞェットのサむズは、子りィゞェットのサむズに䟝存したす


メむンりィンドりが理想的にどのくらいのスペヌスが必芁であるかを知ったので、実際にどのくらいのスペヌスが利甚可胜になるかに぀いお決定が䞋されたす。 劥圓な倀がリク゚ストに含たれおいる堎合、それがデフォルトです。 ただし、りィンドりサむズが手動で蚭定されおいる堎合たずえば、gtk_window_setdefault_sizeを䜿甚、たたはそうでない堎合、りィンドりは芁求されたサむズを砎棄し、別のサむズを蚭定したす。



2番目の段階サむズの割り圓おで、芪りィゞェットから子りィゞェットぞのコマンドが発生したす「ここにスペヌスがありたす。それに合わせおすべおを行いたす。」 りィゞェットに耇数の子りィゞェットがある堎合、このステップのタスクは、子りィゞェット間で空きスペヌスを適切に分割するこずです。



次に、アプリケヌションの䞻芁郚分に進みたす。 私たちは、りィゞェットメニュヌに入り、コンテナセクションに氎平ペむンを遞択し、我々はフレヌム1の䞊に眮きたす。 巊偎は固定サむズである必芁があり、右偎は固定サむズではありたせん。 繰り返したすが、りィゞェットメニュヌに移動し、そこでスクロヌルりィンドりを探したす。 最初に1぀、次に2番目のスクロヌルりィンドりを巊右の区画hpand1氎平ペむンに配眮したす。 scrolledwindow1ず呌ばれる巊偎のScrolled Windowで、プロパティCommonタブでWidth reguestを145に蚭定したす-これは、芁求されたサむズマッチングプロセス甚を意味したす。 scrolledwindow1のResizeプロパティがPackingタブでNoであり 、scrolledwindow2 Yesであるこずも確認する必芁がありたす。

Containersセクションから、最初に最初のViewPortりィゞェットを配眮し、次にscrolledwindow1ずscrolledwindow2の䞡方にそれぞれ2番目のりィゞェットを配眮したす。



画像



サむドメニュヌを芋おみたしょう。 3぀のコンパヌトメントを持぀ViewPort1垂盎ボックスに远加したす。 各コンパヌトメントにラゞオボタンを远加したす。 各ラゞオボタンは、プロパティがありたせんを展開しお蚭定するので、圌らは芪りィゞェットのサむズを増やすこずで䌞びおいたせん。 たた、共通]タブで、あなたは、圌らがデフォルトの代わりに、私たちは䞎えるように倧きさのものであろう幅ず高さの芁求を蚭定するこずができたす。 ただし、いずれにしおもサむズは異なりたす。 [党般]タブでプロパティを倉曎したす。

それぞれrbutRectangle 、 rbutEllipse 、 rbutTriangleの名前

それぞれRectangle 、 Ellipse 、 Triangleにラベルを付けたす

たた、rbutEllipseおよびrbutTriangleの堎合、特別なダむアログを䜿甚しおGroupプロパティrbutRectangleで指定したす。



画像



次のようになりたす。



画像



次に、各ラゞオボタンのむベントを登録する必芁がありたす。 [シグナル]タブでは、GroupChangedむベントずトグルどちらでもかたいたせんのどちらでもかたいたせん。rbutton_toggled_cbハンドラヌを蚘述したす。



画像



次に、りィンドりの右偎に目を向けたす。 2぀のコンパヌトメントを持぀垂盎ボックスをViewPort2に远加したす。 䞊郚に通垞のラベルを配眮し、䞋郚の描画領域にキャンバスを配眮したす。 Label1の堎合、labelプロパティに300 x 200 Canvasを蚘述したす。 [パッキング]タブに移動し、[展開]を[ いいえ ]に蚭定したす。

今、私たちのキャンバス。

名前 drawingarea

支出 いいえ

幅リク゚スト 300

高さリク゚スト 200

むベント 露出を確認



[Signals]で、expose-eventを探し、リストから曞き蟌むか遞択したす。

drawingarea_expose_event_cb



画像



次に、ステヌタスバヌ䞀番䞋のコンパヌトメントずメむンメニュヌ䞀番䞊のコンパヌトメントを远加する必芁がありたす。 メニュヌバヌりィゞェットメニュヌの[コンテナ]セクションを最䞊郚に配眮し、ステヌタスバヌの最䞋郚のコンパヌトメントりィゞェットメニュヌの[コントロヌルず衚瀺]セクションに、远加に関するダむアログが衚瀺されたす。[アむテム数1]を遞択したす。



画像



この䟋のmenubar1では、メニュヌ項目を1぀だけ残したす-プログラムを終了したす。 したがっお、あなたが削陀するこずができたす。menuitem2、menuitem3、menuitem4を。 その埌、我々はmenuitem1を明らかにし、䞭に入るず、すべおを削陀しおもそうimagemenuitem5 MENU1。 これはQuitアむテムです。 これをクリックしお、プロパティりィンドりの[党般]タブのプロパティ、Stock Itemプロパティを芋るこずができたす。このプロパティにはgtk-quitが登録されおいたす。 そこで「遊ぶ」こずができたす。 通垞、カスタムラベルず画像を遞択し、すべおを自分で蚭定できたす。 これはそれほど重芁ではありたせん。 imagemenuitem5の堎合、Signalsタブで、フォヌムを閉じる堎合ずたったく同じように topWindow_destroy_cb 信号のアクティベヌト信号メニュヌ項目をクリックを蚭定したす。



これが、むンタヌフェヌスが最終的にどのように芋えるかです。 mainFormずいう名前でプロゞェクトを保存したす。 ファむルはmainForm.gladeずいう名前になりたす



画像



プログラムのコヌド



Example1.cppあなたがmainForm.gladeを保存した同じフォルダにファむルを䜜成したす。 最初にコヌド党䜓を説明し、次にいく぀かの重芁なポむントを説明したす。



 /* Example1.cpp */ #include <cairo.h> #include <gtk/gtk.h> #define UI_FILE "mainForm.glade" //   GtkBuilder *builder; GtkWidget *topWindow; GtkRadioButton *rbutRectangle, *rbutEllipse, *rbutTriangle; GtkDrawingArea *drawingarea; //    extern "C" void topWindow_destroy_cb (GtkObject *object, gpointer user_data); extern "C" gboolean drawingarea_expose_event_cb(GtkWidget *widget, GdkEventExpose *event, gpointer data); extern "C" void rbutton_toggled_cb (GtkObject *object); int main( int argc, char **argv ) { GError *error = NULL; //  GTK+ gtk_init( &argc, &argv ); //   GtkBuilder  builder = gtk_builder_new(); //     ,     Glade if( ! gtk_builder_add_from_file( builder, UI_FILE, &error ) ) { g_warning( "%s", error->message ); g_free( error ); return( 1 ); } //        GladeXML topWindow = GTK_WIDGET(gtk_builder_get_object(builder, "topWindow")); rbutRectangle = GTK_RADIO_BUTTON(gtk_builder_get_object(builder, "rbutRectangle")); rbutEllipse = GTK_RADIO_BUTTON(gtk_builder_get_object(builder, "rbutEllipse")); rbutTriangle = GTK_RADIO_BUTTON(gtk_builder_get_object(builder, "rbutTriangle")); drawingarea = GTK_DRAWING_AREA(gtk_builder_get_object(builder, "drawingarea")); //       gtk_builder_connect_signals (builder, NULL); //   g_object_unref( G_OBJECT( builder ) ); //       gtk_widget_show( topWindow ); //     gtk_main(); return( 0 ); } //   void topWindow_destroy_cb (GtkObject *object, gpointer user_data) { //     gtk_main_quit(); } //   gboolean drawingarea_expose_event_cb(GtkWidget *widget, GdkEventExpose *event, gpointer data) { cairo_t *cr; cr = gdk_cairo_create (widget->window); cairo_set_line_width (cr, 7); cairo_set_source_rgb (cr, 0, 0, 0); //     if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(rbutRectangle))) { //   cairo_rectangle (cr, 20, 20, 200, 100); cairo_stroke_preserve(cr); cairo_set_source_rgb(cr, 0, 0.8, 0); } //     if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(rbutEllipse))) { //   cairo_arc(cr, 150, 100, 90, 0, 2 * 3.14); cairo_stroke_preserve(cr); cairo_set_source_rgb(cr, 0.8, 0, 0); } //     if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(rbutTriangle))) { //   cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); cairo_move_to (cr, 40, 40); cairo_line_to (cr, 200, 40); cairo_line_to (cr, 120, 160); cairo_line_to (cr, 40, 40); cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND); cairo_stroke_preserve(cr); cairo_set_source_rgb(cr, 0.8, 0, 0.8); } cairo_fill(cr); cairo_destroy(cr); return FALSE; } void rbutton_toggled_cb (GtkObject *object) { //  drawingarea gtk_widget_queue_draw (GTK_WIDGET(drawingarea)); }
      
      



。 /* Example1.cpp */ #include <cairo.h> #include <gtk/gtk.h> #define UI_FILE "mainForm.glade" // GtkBuilder *builder; GtkWidget *topWindow; GtkRadioButton *rbutRectangle, *rbutEllipse, *rbutTriangle; GtkDrawingArea *drawingarea; // extern "C" void topWindow_destroy_cb (GtkObject *object, gpointer user_data); extern "C" gboolean drawingarea_expose_event_cb(GtkWidget *widget, GdkEventExpose *event, gpointer data); extern "C" void rbutton_toggled_cb (GtkObject *object); int main( int argc, char **argv ) { GError *error = NULL; // GTK+ gtk_init( &argc, &argv ); // GtkBuilder builder = gtk_builder_new(); // , Glade if( ! gtk_builder_add_from_file( builder, UI_FILE, &error ) ) { g_warning( "%s", error->message ); g_free( error ); return( 1 ); } // GladeXML topWindow = GTK_WIDGET(gtk_builder_get_object(builder, "topWindow")); rbutRectangle = GTK_RADIO_BUTTON(gtk_builder_get_object(builder, "rbutRectangle")); rbutEllipse = GTK_RADIO_BUTTON(gtk_builder_get_object(builder, "rbutEllipse")); rbutTriangle = GTK_RADIO_BUTTON(gtk_builder_get_object(builder, "rbutTriangle")); drawingarea = GTK_DRAWING_AREA(gtk_builder_get_object(builder, "drawingarea")); // gtk_builder_connect_signals (builder, NULL); // g_object_unref( G_OBJECT( builder ) ); // gtk_widget_show( topWindow ); // gtk_main(); return( 0 ); } // void topWindow_destroy_cb (GtkObject *object, gpointer user_data) { // gtk_main_quit(); } // gboolean drawingarea_expose_event_cb(GtkWidget *widget, GdkEventExpose *event, gpointer data) { cairo_t *cr; cr = gdk_cairo_create (widget->window); cairo_set_line_width (cr, 7); cairo_set_source_rgb (cr, 0, 0, 0); // if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(rbutRectangle))) { // cairo_rectangle (cr, 20, 20, 200, 100); cairo_stroke_preserve(cr); cairo_set_source_rgb(cr, 0, 0.8, 0); } // if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(rbutEllipse))) { // cairo_arc(cr, 150, 100, 90, 0, 2 * 3.14); cairo_stroke_preserve(cr); cairo_set_source_rgb(cr, 0.8, 0, 0); } // if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(rbutTriangle))) { // cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); cairo_move_to (cr, 40, 40); cairo_line_to (cr, 200, 40); cairo_line_to (cr, 120, 160); cairo_line_to (cr, 40, 40); cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND); cairo_stroke_preserve(cr); cairo_set_source_rgb(cr, 0.8, 0, 0.8); } cairo_fill(cr); cairo_destroy(cr); return FALSE; } void rbutton_toggled_cb (GtkObject *object) { // drawingarea gtk_widget_queue_draw (GTK_WIDGET(drawingarea)); }







たず、これらのオブゞェクトを宣蚀したす。 誰ず我々は働きたす。 次に、シグナルハンドラの登録を開始したす。 なぜなら C ++で蚘述し、extern“ C”を䜿甚しお、倖郚関数によっおtopWindow_destroy_cb、drawingarea_expose_event_cb、rbutton_toggled_cbを宣蚀し、Cのバむンディング順序に埓っおリンクする必芁があるこずを瀺したす。GtkBuilderにはGladeの蚘述からのすべおのオブゞェクトぞのリンクが含たれたす。 gtk_builder_get_object関数は、GtkBuilderこの堎合はビルダヌから察応する名前を持぀オブゞェクトぞの参照を取埗したす。 gtk_builder_connect_signals関数を䜿甚しお、コヌド内のハンドラヌ関数をGladeXMLの察応するシグナルハンドラヌに接続したす。 これは自動的に行われたす。 Gladeずコヌドの名前が䞀臎するこずが重芁です。 アプリケヌションは正垞にコンパむルされ、シグナルだけが凊理されたせん。コン゜ヌルからプログラムを実行するず、そのようなシグナルのハンドラヌを芋぀けるこずができないずいう譊告が衚瀺されたす。



たた、 C ++で蚘述する堎合、明瀺的な型倉換を䜿甚する必芁が非垞に倚くありたす。 䟋えば

 rbutRectangle = GTK_RADIO_BUTTON(gtk_builder_get_object(builder, "rbutRectangle"));
      
      







Cで蚘述した堎合、GTK_RADIO_BUTTONの明瀺的なゎヌストなしで実行できたす。



プログラムをコンパむルするには、自動ビルドシステムCMakeなどを䜿甚するか、メむクファむルを自分で登録する必芁がありたす。 これに぀いおは詳しく説明したせん。 そしお、makefileの説明の䟋を挙げおください。 ポストの終わりに蚭立に関する最近の2぀の参照は、単にファむルを䜜りたす。



 CC=g++ LDLIBS=`pkg-config --libs gtk+-2.0 gmodule-2.0` CFLAGS=-Wall -g `pkg-config --cflags gtk+-2.0 gmodule-2.0` Example1: Example1.o $(CC) $(LDLIBS) Example1.o -o Example1 Example1.o: Example1.cpp $(CC) $(CFLAGS) -c Example1.cpp clean: rm -f Example1 rm -f *.o
      
      







コンパむルはコマンドです。

 make
      
      







私たちのプログラムの小芏暡なテスト





èµ·å‹•äž­...



画像



...そしおりィンドりのサむズを倉曎したす



画像



サむドメニュヌずキャンバスは䌞びず、同じ寞法のたたでしたが、キャンバスが寞法を倉曎したコンテナが衚瀺されおいたす。 そしお、どこフォヌムのサむズの増加に䌎っお登堎し、すべおの空き領域が、圌を埗たした。 私たちが幅= 145 reguest scrolledwindow1を確立し、 はいサむズを倉曎しおいるので、これがすべおです。 メむンりィンドりが小さくなったずきに衚瀺されるスクロヌルバヌの䟋を次に瀺したす



画像



そしお今、私はYesにプロパティを展開Glade3に来お、LABEL1に倉曎されたした。 プロゞェクトを再コンパむルする必芁はありたせん。 mainFormファむルを保存するだけです。 結果は次のずおりです。



画像



なぜそう 固定サむズのキャンバスがありたす。 たた、メむンりィンドりを拡倧したずきに取埗されるすべおのスペヌスは、label1りィゞェットに䞎えられたす。 このすべおのビゞネスで「遊ぶ」こずができたす。 たずえば、[展開]を[いいえ]に蚭定し、正確な高さの倀70などを指定したす。たた、既定のサむズではなく、指定したサむズに固定されたす。



これでこの投皿は終了です。 トピックは面癜いですが、私はこの方向でより倚くの蚘事を曞きたいずいう願望を持っおいたす。



Glade3のチュヌトリアル-サむズネゎシ゚ヌションから少しの理論が埗られたす。

私はあなたが読むこずをお勧めし のパッキングりィゞェットを 、 カむログラフィックチュヌトリアルの 、 Makefileの䟋による 、 GNU `make 'を



All Articles