• 検索結果がありません。

メニューバーの追加

ドキュメント内 ÆþÌçGTK+ (ページ 35-40)

第2章 GTK+ で画像ビューワを作ってみよう

第2章 GTK+ で画像ビューワを作ってみよう 24 第2章 GTK+で画像ビューワを作ってみよう

2.7.2 メニュー構成の作成

メニュー構成は,XML形式で指定します.XMLを外部のテキストファイルに記述するか,その内容をソースコード中に文 字列として保持するか,いずれかの方法で作成します.今回はメニュー構成を文字列として作成し,ソースコード中に埋め込む ことにします.今回作成するメニューの構成は,次のような文字列で表されます.

"<interface>"

" <menu id=’appmenu’>"

" <submenu>"

" <attribute name=’label’>File</attribute>"

" <section>"

" <item>"

" <attribute name=’label’>Open</attribute>"

" <attribute name=’action’>app.open</attribute>"

" <attribute name=’accel’>&lt;Primary&gt;o</attribute>"

" </item>"

" </section>"

" <section>"

" <item>"

" <attribute name=’label’>Quit</attribute>"

" <attribute name=’action’>app.quit</attribute>"

" <attribute name=’accel’>&lt;Primary&gt;q</attribute>"

" </item>"

" </section>"

" </submenu>"

" </menu>"

"</interface>";

メニューの構成は,<interface>タグから始まり, <menu></menu>タグ内に記述します. <menu>タグ内の IDは

GtkBuilerを用いて作成したメニューバーの情報を取り出す際の識別子として用いられます. ここでは,メニューバーの中に

Fileメニューがあり,そのメニューアイテムとしてOpenとQuitが存在する構成となっています.この場合, Fileメニューは

<submenu>タブで記述し,<attribute name=’label’>タブでそのラベルを指定します. また, OpenとQuitのメニューアイ

テムは<item>タブで記述します. メニューアイテムの属性は<attribute>タブで記述し,属性の種類をname=’ ’という形で

指定します. メニューアイテムの代表的な属性を以下に挙げます.

label ... メニューアイテムのラベル

action ... GActionEntry構造体の要素と関連付けるための文字列

accel ... メニューアイテムに対するアクセラレータキー

action属性の文字列は, GtkApplication(またはGtkWidget)に関連付けされたGActionMapの識別子と GActio-nEntry構造体の第1メンバであるname変数の文字列を用いて, ”GActionMap識別子.GActionEntryのname文字列”の形式 で記述する必要があります.

また, OpenとQuitの間に仕切り(セパレータ)を配置する場合には,仕切りの前後のメニューアイテムを<section>タブで

挟むようにします.

2.7.3 メニューアイテムに対するコールバック関数の記述

メニューアイテムが選択されたときに呼び出されるコールバック関数の記述は,GActionEntry構造体で行い,以下の5項 目を設定します.

1. メニューアイテムと関連付けするための文字列

2. メニューアイテムが選択されたときに呼び出されるコールバック関数

第2章 GTK+ で画像ビューワを作ってみよう

2.7 メニューバーの追加 25

3. パラメータタイプ 4. 状態

5. メニューアイテムの状態が変わったときに呼び出されるコールバック関数

前項で定義したメニューおよびメニューアイテムの場合は,次のように詳細を設定します.

static GActionEntry entries[] = { {"open", cb_open, NULL, NULL, NULL}, {"quit", cb_quit, NULL, NULL, NULL}, };

特別な処理をしない限りは第3から第5メンバは設定しなくても問題ありませんので,今回はすべてNULLとしています.

2.7.4 コールバック関数の登録

次にGActionEntry構造体で記述したコールバック関数をアプリケーションと関連付けしたGActionMapに登録します.

登録を行うには関数g action map add action entries を使用します. 今回のようにGtkApplicationを使っている場合は, GtkApplication自身をGActioMapとして使用することができます(ソース2–6132–134行目).

v o i d g _ a c t i o n _ m a p _ a d d _ a c t i o n _ e n t r i e s ( G A c t i o n M a p * a c t i o n _ m a p , c o n s t G A c t i o n E n t r y * e n t r i e s ,

g i n t n _ e n t r i e s ,

g p o i n t e r u s e r _ d a t a ) ;

第1引数 GActionMap型の変数へのポインタ

第2引数 GActionEntryで定義されたコールバック関数情報

第3引数 GActionEntryのエントリ数

第4引数 コールバック関数に渡すデータ

2.7.5 メニューバーウィジェットの作成

最後に,GtkBuilerを用いてメニュー定義情報からメニューバーウィジェットを作成して,アプリケーションに配置します.

メニュー定義情報がファイルの場合は,関数gtk builder add from fileを使用します. また,メニュー定義情報が文字列の場 合は,関数gtk builder add from stringを使用します. 以下は, GtkBuilderに文字列で定義したメニュー情報を追加する例に なります.

GtkBuilder *builder = gtk_builder_new ();

gtk_builder_add_from_string (builder, menu_info, -1, NULL);

関数gtk builder add from stringは,文字列からメニュー定義情報を登録する関数です.第3引数にはメニュー構成を示す

文字列の長さを指定しますが,文字列全体を使用する場合には1を指定します.

g u i n t g t k _ b u i l d e r _ a d d _ f r o m _ s t r i n g (G t k B u i l d e r * b u i l d e r , c o n s t g c h a r * b u f f e r , g s i z e l e n g t h , G E r r o r * * e r r o r ) ;

第1引数 GtkBuilder型の変数 第2引数 メニュー構成文字列 第3引数 メニュー構成文字列の長さ

第4引数 エラー情報を格納する変数へのポインタ 戻り値 成功した場合には正の数,エラーの場合には0

第2章 GTK+ で画像ビューワを作ってみよう 26 第2章 GTK+で画像ビューワを作ってみよう

2.7.6 メニューバーウィジェットの取得

すべてのメニュー情報をGtkBuilderに登録したら,関数gtk builder get objectを使用して,メニューバーウィジェットを 取得します.

G O b j e c t * g t k _ b u i l d e r _ g e t _ o b j e c t (G t k B u i l d e r * b u i l d e r , c o n s t g c h a r * n a m e ) ;

第1引数 GtkBuilder型の変数 第2引数 識別文字列

戻り値 取得したオブジェクト

最後に,以下に示すように関数gtk builder get objectで取得したオブジェクトをGMenuModel型のポインタに変換して, 関数gtk application set menubarを使ってアプリケーションに配置します.

GMenuModel *menubar;

menubar = (GMenuModel *) gtk_builder_get_object (builder, "appmenu");

gtk_application_set_menubar (GTK_APPLICATION (app), menubar);

2.7.7 コンパイルと動作確認

ソースコードを入力し,コンパイルしたら,いつものように実行してみましょう.

$ ./image-viewer ~/images/Parrots.png

図2.11のようにメニューバーが表示され,メニューやショートカットキーを利用してプログラムを終了できるようになりまし た.プログラムを終了する際にはコールバック関数(ソース2–618–26行目)が呼び出されますが,関数の第3引数のuser data

にはGtkApplication型の変数が与えられています. これは,ソース2–6122–124行目でコールバック関数をGActionMapに

登録する際に,関数の第3引数にGtkApplication型の変数appを指定しているためです.

図2.11 メニューバーを追加した画像ビューワ

ソース2–6 メニューバーの追加: image-viewer.c

1 # i n c l u d e <g t k / g t k . h >

2 # i n c l u d e <s t d l i b . h >

3 4 / *

5 O p e nメ ニ ュ ー が 選 択 さ れ た と き に 呼 び 出 さ れ る 関 数

第2章 GTK+ で画像ビューワを作ってみよう

2.7 メニューバーの追加 27

6 * /

7 s t a t i c v o i d

8 c b _ o p e n ( G S i m p l e A c t i o n * a c t i o n ,

9 G V a r i a n t * p a r a m t e r ,

10 g p o i n t e r u s e r _ d a t a )

11 {

12 g _ p r i n t ( " T h i s ␣ f u n c t i o n ␣ i s ␣ n o t ␣ i m p l e m e n t e d ␣ y e t . \ n " ) ;

13 }

14 15 / *

16 ボ タ ン が ク リ ッ ク さ れ た と き に 呼 び 出 さ れ る 関 数 17 * /

18 s t a t i c v o i d

19 c b _ q u i t ( G S i m p l e A c t i o n * a c t i o n ,

20 G V a r i a n t * p a r a m e t e r ,

21 g p o i n t e r u s e r _ d a t a )

22 {

23 / * メ イ ン ル ー プ を 終 了 * /

24 G A p p l i c a t i o n * a p p = G _ A P P L I C A T I O N ( u s e r _ d a t a ) ;

25 g _ a p p l i c a t i o n _ q u i t ( a p p ) ;

26 }

27 28 / *

29 * メ ニ ュ ー の 構 造 30 * /

31 s t a t i c c o n s t g c h a r m e n u _ i n f o [ ] =

32 " <i n t e r f a c e > "

33 " ␣ ␣ <m e n u ␣ i d = ’a p p m e n u ’ >"

34 " ␣ ␣ ␣ ␣ <s u b m e n u > "

35 " ␣ ␣ ␣ ␣ ␣ ␣ <a t t r i b u t e ␣ n a m e = ’l a b e l ’ >F i l e < / a t t r i b u t e > "

36 " ␣ ␣ ␣ ␣ ␣ ␣ <s e c t i o n > "

37 " ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ <i t e m > "

38 " ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ <a t t r i b u t e ␣ n a m e = ’l a b e l ’ >O p e n < / a t t r i b u t e > "

39 " ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ <a t t r i b u t e ␣ n a m e = ’a c t i o n ’ >a p p . o p e n < / a t t r i b u t e > "

40 " ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ <a t t r i b u t e ␣ n a m e = ’a c c e l ’ >&l t ; P r i m a r y & g t ; o < / a t t r i b u t e > "

41 " ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ </i t e m > "

42 " ␣ ␣ ␣ ␣ ␣ ␣ </s e c t i o n > "

43 " ␣ ␣ ␣ ␣ ␣ ␣ <s e c t i o n > "

44 " ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ <i t e m > "

45 " ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ <a t t r i b u t e ␣ n a m e = ’l a b e l ’ >Q u i t < / a t t r i b u t e > "

46 " ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ <a t t r i b u t e ␣ n a m e = ’a c t i o n ’ >a p p . q u i t < / a t t r i b u t e > "

47 " ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ <a t t r i b u t e ␣ n a m e = ’a c c e l ’ >&l t ; P r i m a r y & g t ; q < / a t t r i b u t e > "

48 " ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ </i t e m > "

49 " ␣ ␣ ␣ ␣ ␣ ␣ </s e c t i o n > "

50 " ␣ ␣ ␣ ␣ </s u b m e n u > "

51 " ␣ ␣ </m e n u > "

52 " </i n t e r f a c e > " ;

53 54 / *

55 * メ ニ ュ ー ア イ テ ム の 詳 細 56 * /

57 s t a t i c G A c t i o n E n t r y e n t r i e s [ ] = {

58 { " o p e n " , c b _ o p e n , N U L L , N U L L , N U L L } ,

59 { " q u i t " , c b _ q u i t , N U L L , N U L L , N U L L } ,

60 } ;

61 62 / *

63 * ア プ リ ケ ー シ ョ ン が 有 効 に な っ た と き に 呼 び 出 さ れ る 関 数 64 * /

65 s t a t i c v o i d c b _ a c t i v a t e ( G A p p l i c a t i o n * app ,

66 g p o i n t e r u s e r _ d a t a )

67 {

68 G t k W i d g e t * w i n d o w ;

69

70 / * ウ ィ ン ド ウ の 作 成 * /

71 w i n d o w = g t k _ a p p l i c a t i o n _ w i n d o w _ n e w ( G T K _ A P P L I C A T I O N ( a p p ) ) ;

72 / * ウ ィ ン ド ウ の 大 き さ の 設 定 * /

73 g t k _ w i d g e t _ s e t _ s i z e _ r e q u e s t ( w i n d o w , 3 0 0 , 2 0 0 ) ;

74 / * メ ニ ュ ー の 作 成 * /

75 G t k B u i l d e r * b u i l d e r ;

76 b u i l d e r = g t k _ b u i l d e r _ n e w ( ) ;

77 g t k _ b u i l d e r _ a d d _ f r o m _ s t r i n g ( b u i l d e r , m e n u _ i n f o , -1 , N U L L ) ;

78 G M e n u M o d e l * m e n u b a r ;

79 m e n u b a r = ( G M e n u M o d e l * ) g t k _ b u i l d e r _ g e t _ o b j e c t ( b u i l d e r , " a p p m e n u " ) ;

80 g t k _ a p p l i c a t i o n _ s e t _ m e n u b a r ( G T K _ A P P L I C A T I O N ( a p p ) , m e n u b a r ) ;

81 {

第2章 GTK+ で画像ビューワを作ってみよう 28 第2章 GTK+で画像ビューワを作ってみよう

82 / * ス ク ロ ー ル バ ー 付 き ウ ィ ン ド ウ の 作 成 * /

83 G t k W i d g e t * s c r o l l _ w i n d o w ;

84 s c r o l l _ w i n d o w = g t k _ s c r o l l e d _ w i n d o w _ n e w ( N U L L , N U L L ) ;

85 / * ス ク ロ ー ル バ ー 付 き ウ ィ ン ド ウ を 配 置 * /

86 g t k _ c o n t a i n e r _ a d d ( G T K _ C O N T A I N E R ( w i n d o w ) , s c r o l l _ w i n d o w ) ;

87 / * ス ク ロ ー ル バ ー の 表 示 設 定 * /

88 g t k _ s c r o l l e d _ w i n d o w _ s e t _ p o l i c y ( G T K _ S C R O L L E D _ W I N D O W ( s c r o l l _ w i n d o w ) ,

89 G T K _ P O L I C Y _ A U T O M A T I C ,

90 G T K _ P O L I C Y _ A U T O M A T I C ) ;

91 {

92 G t k W i d g e t * i m a g e ;

93

94 / * フ ァ イ ル か ら 画 像 を 読 み 込 ん で イ メ ー ジ の 作 成 * /

95 i m a g e = g t k _ i m a g e _ n e w _ f r o m _ f i l e ( (c h a r * ) u s e r _ d a t a ) ;

96 / * イ メ ー ジ を ス ク ロ ー ル バ ー 付 き ウ ィ ン ド ウ に 配 置 * /

97 g t k _ c o n t a i n e r _ a d d ( G T K _ C O N T A I N E R ( s c r o l l _ w i n d o w ) , i m a g e ) ;

98 }

99 }

100 / * ウ ィ ン ド ウ の 表 示 * /

101 g t k _ w i d g e t _ s h o w _ a l l ( w i n d o w ) ;

102 }

103 104 / *

105 メ イ ン 関 数 106 * /

107 i n t

108 m a i n (i n t ar g c , c h a r * * a r g v )

109 {

110 G t k A p p l i c a t i o n * a p p ;

111 G t k W i d g e t * w i n d o w ;

112

113 / * 引 数 の チ ェ ッ ク * /

114 i f ( a r g c ! = 2 )

115 {

116 g _ p r i n t ( " U s a g e : ␣ % s ␣ i m a g e - f i l e \ n " , a r g v [ 0 ] ) ;

117 e x i t ( 1 ) ;

118 }

119 / * ア プ リ ケ ー シ ョ ン の 作 成 * /

120 a p p = g t k _ a p p l i c a t i o n _ n e w ( " t e s t . g t k . i m a g e v i e w e r " , 0 ) ;

121 / * ア ク シ ョ ン の 登 録 * /

122 g _ a c t i o n _ m a p _ a d d _ a c t i o n _ e n t r i e s ( G _ A C T I O N _ M A P ( a p p ) ,

123 e n t r i e s , G _ N _ E L E M E N T S ( e n t r i e s ) ,

124 a p p ) ;

125 / * シ グ ナ ル ハ ン ド ラ の 登 録 * /

126 g _ s i g n a l _ c o n n e c t ( app , " a c t i v a t e " , G _ C A L L B A C K ( c b _ a c t i v a t e ) , a r g v [ 1 ] ) ;

127 / * メ イ ン ル ー プ * /

128 g _ a p p l i c a t i o n _ r u n ( G _ A P P L I C A T I O N ( a p p ) , 0 , N U L L ) ;

129

130 r e t u r n 0 ;

131 }

2.7.8 まとめ

GtkBuilderを利用することで簡単にメニューが作成できるとはいえ,メニューを作成するまでにさまざまな手順が必要でし

た.メニュー作成の手順をもう一度簡単にまとめておきます.

1. メニュー構成の記述

今回は文字列で定義しましたが,テキストファイルに定義する方法もあります.

2. コールバック関数の記述

3. コールバック関数をアプリケーションに登録 4. メニューバーの取得とアプリケーションへの配置

ドキュメント内 ÆþÌçGTK+ (ページ 35-40)

関連したドキュメント