第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. メニューバーの取得とアプリケーションへの配置
第2章 GTK+ で画像ビューワを作ってみよう
2.8 ファイル選択ダイアログの実装 29
2.8.1 ファイル選択ダイアログの作成
ファイル選択ダイアログを作成する関数はgtk file chooser dialog newです.選択した画像ファイルを開いて表示するダイ アログは,次のように作成します.
GtkWidget *dialog;
dialog = gtk_file_chooser_dialog_new ("Open an image", GTK_WINDOW (window),
GTK_FILE_CHOOSER_ACTION_OPEN,
"_Cancel", GTK_RESPONSE_CANCEL,
"_Open", GTK_RESPONSE_ACCEPT, NULL);
関数gtk file chooser dialog newの引数は,以下の通りです.
G t k W i d g e t* g t k _ f i l e _ c h o o s e r _ d i a l o g _ n e w (c o n s t g c h a r * t i t l e , G t k W i n d o w * p a r e n t ,
G t k F i l e C h o o s e r A c t i o n a c t i o n , c o n s t g c h a r * f i r s t _ b u t t o n _ t e x t , . . . ) ;
第1引数 ダイアログのタイトル 第2引数 親ウィンドウ
第3引数 ダイアログの種類(開くか保存か)
第4引数 追加するボタンのアイコン 第5引数 ボタンを押したときの応答ID 戻り値 生成したファイル選択ダイアログ
この関数の第2引数には,ダイアログの呼び出し元になる親ウィンドウを指定します.ダイアログを操作している間は,この ウィンドウに対する操作ができない状態になります.第3引数には,このダイアログの種類を指定します.今回はファイルを開 く目的なので,GTK FILE CHOOSER ACTION OPENを指定しています.指定したファイル名で保存するダイアログを作 成するならば,GTK FILE CHOOSER ACTION SAVEを指定します.
第4,5引数以降は2つ1組で与え,それぞれ追加するボタンのラベルと,どのボタンが押されたかを知るための応答IDを 指定します.この例では,「キャンセル」ボタンと「開く」ボタンをダイアログに追加して,「キャンセル」が押されたときに
GTK RESPONSE CANCELというIDが,「開く」ではGTK RESPONSE ACCEPTが返ってくるように設定しています.
引数の終わりには必ずNULLを与えます.
2.8.2 ファイル名の取得と画像の表示
ダイアログを作成したら,次にそのダイアログを表示してファイルを選択する処理を行います.ファイル選択処理を開始する には,関数gtk dialog runを呼び出します.
gint response;
response = gtk_dialog_run (GTK_DIALOG (dialog));
ファイルの選択処理が終わると(ファイルを選択して「開く」ボタンを押すか,「キャンセル」ボタンを押した場合に処理が終 了する),この関数の戻り値として,ダイアログ作成時に設定した応答IDが返ってきます.
g i n t g t k _ d i a l o g _ r u n (G t k D i a l o g * d i a l o g ) ;
第1引数 ダイアログ 戻り値 応答ID
第2章 GTK+ で画像ビューワを作ってみよう 30 第2章 GTK+で画像ビューワを作ってみよう
ダイアログでファイルを選択した場合(関数gtk dialog runの戻り値としてGTK RESPONSE ACCEPTが返ってきた場 合),選択したファイル名を取得し,イメージウィジェットを作成して表示します.
まず次のように,選択したファイル名を取得します.
gchar *filename;
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
そして,イメージウィジェットの機能を使用して,指定した画像ファイルから画像を表示します.
gtk_image_set_from_file (GTK_IMAGE (image), filename);
最後に,関数gtk file chooser get filenameによって取得した文字列のためのメモリ領域を,関数g freeで解放します.
2.8.3 コンパイルと動作確認
ソース2–7を入力して,コンパイルしてプログラムを完成させてみましょう.
今回の実装でダイアログからファイルを指定して画像を表示させられるようになったので,プログラムの実行時にファイル 名を指定する必要がなくなりました.それにともない,ソースコードの131行目で,関数gtk image newを使用して,空のイ メージウィジェットを作成するようにしています.
プログラムを実行したら,早速ファイル選択ダイアログからファイルを選択して,画像を表示してみましょう.図2.12のよ うに,ダイアログから選択した画像を表示できたでしょうか.
ソース2–7 画像ビューワ完成版: 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メ ニ ュ ー が 選 択 さ れ た と き に 呼 び 出 さ れ る 関 数
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 t k A p p l i c a t i o n * a p p ;
13 G t k W i n d o w * w i n d o w ;
14 G t k W i d g e t * d i a l o g ;
15 g i n t r e s p o n s e ;
16
17 / * ウ ィ ン ド ウ の 取 得 * /
18 a p p = G T K _ A P P L I C A T I O N ( u s e r _ d a t a ) ;
19 w i n d o w = g t k _ a p p l i c a t i o n _ g e t _ a c t i v e _ w i n d o w ( a p p ) ;
20 / * フ ァ イ ル 選 択 ダ イ ア ロ グ の 作 成 * /
21 d i a l o g = g t k _ f i l e _ c h o o s e r _ d i a l o g _ n e w ( " O p e n ␣ a n ␣ i m a g e " ,
22 G T K _ W I N D O W ( w i n d o w ) ,
23 G T K _ F I L E _ C H O O S E R _ A C T I O N _ O P E N ,
24 " _ C a n c e l " ,
25 G T K _ R E S P O N S E _ C A N C E L ,
26 " _ O p e n " ,
27 G T K _ R E S P O N S E _ A C C E P T ,
28 N U L L ) ;
29 / * ダ イ ア ロ グ の 表 示 * /
30 g t k _ w i d g e t _ s h o w _ a l l ( d i a l o g ) ;
31 / * ダ イ ア ロ グ に よ る フ ァ イ ル 選 択 処 理 * /
32 r e s p o n s e = g t k _ d i a l o g _ r u n ( G T K _ D I A L O G ( d i a l o g ) ) ;
33 i f ( r e s p o n s e = = G T K _ R E S P O N S E _ A C C E P T )
34 {
35 g c h a r * f i l e n a m e ;
36 G t k W i d g e t * i m a g e ;
37
38 / * 選 択 し た フ ァ イ ル 名 の 取 得 * /
39 f i l e n a m e = g t k _ f i l e _ c h o o s e r _ g e t _ f i l e n a m e ( G T K _ F I L E _ C H O O S E R ( d i a l o g ) ) ;
第2章 GTK+ で画像ビューワを作ってみよう
2.8 ファイル選択ダイアログの実装 31
(a)ファイル選択ダイアログ
(b)選択した画像の表示 図2.12 完成した画像ビューワ
40 / * イ メ ー ジ の 取 得 * /
41 i m a g e = G T K _ W I D G E T ( g _ o b j e c t _ g e t _ d a t a ( G _ O B J E C T ( w i n d o w ) , " i m a g e " ) ) ;
42 / * フ ァ イ ル か ら 画 像 を 読 み 込 ん で イ メ ー ジ に セ ッ ト * /
43 g t k _ i m a g e _ s e t _ f r o m _ f i l e ( G T K _ I M A G E ( i m a g e ) , f i l e n a m e ) ;
44 / * 文 字 列 領 域 の 解 放 * /
45 g _ f r e e ( f i l e n a m e ) ;
46 }
47 / * ダ イ ア ロ グ の 破 棄 * /
48 g t k _ w i d g e t _ d e s t r o y ( d i a l o g ) ;
49 }
50 51 / *
52 ボ タ ン が ク リ ッ ク さ れ た と き に 呼 び 出 さ れ る 関 数 53 * /
54 s t a t i c v o i d
55 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 ,
56 G V a r i a n t * p a r a m e t e r ,
57 g p o i n t e r u s e r _ d a t a )
第2章 GTK+ で画像ビューワを作ってみよう 32 第2章 GTK+で画像ビューワを作ってみよう
58 {
59 / * メ イ ン ル ー プ を 終 了 * /
60 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 ) ;
61 g _ a p p l i c a t i o n _ q u i t ( a p p ) ;
62 }
63 64 / *
65 * メ ニ ュ ー の 構 造 66 * /
67 s t a t i c c o n s t g c h a r m e n u _ i n f o [ ] =
68 " <i n t e r f a c e > "
69 " ␣ ␣ <m e n u ␣ i d = ’a p p m e n u ’ >"
70 " ␣ ␣ ␣ ␣ <s u b m e n u > "
71 " ␣ ␣ ␣ ␣ ␣ ␣ <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 > "
72 " ␣ ␣ ␣ ␣ ␣ ␣ <s e c t i o n > "
73 " ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ <i t e m > "
74 " ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ <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 > "
75 " ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ <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 > "
76 " ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ <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 > "
77 " ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ </i t e m > "
78 " ␣ ␣ ␣ ␣ ␣ ␣ </s e c t i o n > "
79 " ␣ ␣ ␣ ␣ ␣ ␣ <s e c t i o n > "
80 " ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ <i t e m > "
81 " ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ <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 > "
82 " ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ <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 > "
83 " ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ <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 > "
84 " ␣ ␣ ␣ ␣ ␣ ␣ ␣ ␣ </i t e m > "
85 " ␣ ␣ ␣ ␣ ␣ ␣ </s e c t i o n > "
86 " ␣ ␣ ␣ ␣ </s u b m e n u > "
87 " ␣ ␣ </m e n u > "
88 " </i n t e r f a c e > " ;
89 90 / *
91 * メ ニ ュ ー ア イ テ ム の 詳 細 92 * /
93 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 [ ] = {
94 { " o p e n " , c b _ o p e n , N U L L , N U L L , N U L L } ,
95 { " q u i t " , c b _ q u i t , N U L L , N U L L , N U L L } ,
96 } ;
97 98 / *
99 * ア プ リ ケ ー シ ョ ン が 有 効 に な っ た と き に 呼 び 出 さ れ る 関 数 100 * /
101 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 ,
102 g p o i n t e r u s e r _ d a t a )
103 {
104 G t k W i d g e t * w i n d o w ;
105
106 / * ウ ィ ン ド ウ の 作 成 * /
107 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 ) ) ;
108 / * ウ ィ ン ド ウ の 大 き さ の 設 定 * /
109 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 ) ;
110 / * メ ニ ュ ー の 作 成 * /
111 G t k B u i l d e r * b u i l d e r ;
112 b u i l d e r = g t k _ b u i l d e r _ n e w ( ) ;
113 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 ) ;
114 G M e n u M o d e l * m e n u b a r ;
115 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 " ) ;
116 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 ) ;
117 {
118 / * ス ク ロ ー ル バ ー 付 き ウ ィ ン ド ウ の 作 成 * /
119 G t k W i d g e t * s c r o l l _ w i n d o w ;
120 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 ) ;
121 / * ス ク ロ ー ル バ ー 付 き ウ ィ ン ド ウ を 配 置 * /
122 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 ) ;
123 / * ス ク ロ ー ル バ ー の 表 示 設 定 * /
124 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 ) ,
125 G T K _ P O L I C Y _ A U T O M A T I C ,
126 G T K _ P O L I C Y _ A U T O M A T I C ) ;
127 {
128 G t k W i d g e t * i m a g e ;
129
130 / * フ ァ イ ル か ら 画 像 を 読 み 込 ん で イ メ ー ジ の 作 成 * /
131 i m a g e = g t k _ i m a g e _ n e w ( ) ;
132 / * ウ ィ ン ド ウ に イ メ ー ジ を デ ー タ と し て セ ッ ト * /
第2章 GTK+ で画像ビューワを作ってみよう
2.8 ファイル選択ダイアログの実装 33
133 g _ o b j e c t _ s e t _ d a t a ( G _ O B J E C T ( w i n d o w ) , " i m a g e " , (g p o i n t e r) i m a g e ) ;
134 / * イ メ ー ジ を ス ク ロ ー ル バ ー 付 き ウ ィ ン ド ウ に 配 置 * /
135 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 ) ;
136 }
137 }
138 / * ウ ィ ン ド ウ の 表 示 * /
139 g t k _ w i d g e t _ s h o w _ a l l ( w i n d o w ) ;
140 }
141 142 / *
143 メ イ ン 関 数 144 * /
145 i n t
146 m a i n (i n t a r g c , c h a r * * a r g v )
147 {
148 G t k A p p l i c a t i o n * a p p ;
149
150 / * ア プ リ ケ ー シ ョ ン の 作 成 * /
151 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 ) ;
152 / * ア ク シ ョ ン の 登 録 * /
153 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 ) ,
154 e n t r i e s , G _ N _ E L E M E N T S ( e n t r i e s ) ,
155 a p p ) ;
156 / * シ グ ナ ル ハ ン ド ラ の 登 録 * /
157 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 ) , N U L L ) ;
158 / * メ イ ン ル ー プ * /
159 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 ) ;
160
161 r e t u r n 0 ;
162 }
2.8.4 まとめ
チュートリアル最後となる本節では,ファイル選択ダイアログを実装して,ダイアログから指定した画像を表示できるように しました.今回解説した内容は以下の通りです.
• ファイル選択ダイアログの作成
• ダイアログからのファイル名の取得
このチュートリアルもこれで終了です.単純なウィンドウの作成に始まり,最終的にはメニューからダイアログを表示させ,
指定した画像を表示する画像ビューワを完成させました.それぞれの節で説明を省略しているので,完全には内容を理解できな かったかもしれませんが,このようなアプリケーションを比較的簡単に作成できることがわかってもらえたのではないでしょ うか.
次の章からは,GTK+や関連する内容について詳しく説明していきます.チュートリアルでは語りきれなかったGTK+の 魅力がたっぷりと詰まっています.是非読み進めてください.