前回の GTK+ コードでコンパイル時に WARNING が出ていた件が解決した。
valac はオプションに -C を入れるとコンパイル前に C 言語に変換されたソースコードを吐き出す。
コレを利用してどのように変換されたかを調べる。
1 2 3 | private void on_clicked(Button button) { var f = File.new_for_path( "gtk.txt" ); var fstream = f.replace( null , false , FileCreateFlags.NONE); |
# valac -C --pkg gtk+-3.0 hoge.vala
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | static void win_on_clicked (Win* self, GtkButton* button) { GFile* _tmp0_ = NULL; GFile* f; GFileOutputStream* _tmp2_ = NULL; GFileOutputStream* fstream; GError * _inner_error_ = NULL; g_return_if_fail (self != NULL); g_return_if_fail (button != NULL); _tmp0_ = g_file_new_for_path ( "gtk.txt" ); f = _tmp0_; _tmp1_ = f; _tmp2_ = g_file_replace (_tmp1_, NULL, FALSE, G_FILE_CREATE_NONE, NULL, &_inner_error_); fstream = _tmp2_; if (_inner_error_ != NULL) { _g_object_unref0 (f); g_critical ( "file %s: line %d: uncaught error: %s (%s, %d)" , __FILE__, __LINE__, _inner_error_->message, g_quark_to_string (_inner_error_->domain), _inner_error_->code); g_clear_error (&_inner_error_); return ; } |
どうやら GError にてチェックを行う関数はすべて確認コードを生成するようである。
ところが Vala で書く場合は GError を ref で入れることができない。
このような場合 try,catch 文にすれば GError が渡ってくるようだ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | private void on_clicked(Button button) { File f; FileOutputStream fstream; DataOutputStream dstream; f = File.new_for_path( "gtk.txt" ); try { fstream = f.replace( null , false , FileCreateFlags.NONE); } catch (Error e) { stderr.printf ( "Error: %s\n" , e.message); return ; } dstream = new DataOutputStream(fstream); try { dstream.put_string(entry.get_text()); } catch (IOError e) { stderr.printf ( "Error: %s\n" , e.message); return ; } } |
ついでに解ったけど FileOutputStream は関数を抜けると勝手に close される。
エラーなんて絶対に起こらないし厳密すぎだしこんなの面倒くさいよ!
という場合は以下みたいな超手抜きコードでイケる。
1 2 3 4 5 6 7 8 9 | private void on_clicked() { try { var f = File.new_for_path( "gtk.txt" ); var fstream = f.replace( null , false , FileCreateFlags.NONE); var dstream = new DataOutputStream(fstream); dstream.put_string(entry.get_text()); } catch { } } |
前回のコードの on_clicked 関数をこう書き換えれば確認できる。
これで WARNING とはおさらば。
それとせっかく GTK+ を使うのに printf は無いだろう。
やはりココはエラーメッセージをダイアログで出したい。
C# からの乗り換えでは MessageBox.Show() を使いたい。
ということで簡易なものを作ってみた。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | using Gtk; public class MessageBox { public static ResponseType Show ( string text) { var dlg = new MessageDialog( null , DialogFlags.MODAL, MessageType.WARNING, ButtonsType.OK, text ); dlg.set_title( "TitleBar" ); var res = dlg.run(); dlg.destroy(); return (ResponseType)res; } } public static int main ( string [] args) { Gtk.init( ref args); MessageBox.Show( "MessageBox.Show Test" ); return 0; } |
やはり PyGI で書くのとほとんど変わらない。
var と new と中括弧とセミコロン、他少々書くことが増えただけ。
ちなみに Python ではこんな感じ。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #!/usr/bin/env python #-*- coding:utf-8 -*- from gi.repository import Gtk class MessageBox: @staticmethod def Show (text): dlg = Gtk.MessageDialog( None , Gtk.DialogFlags.MODAL, Gtk.MessageType.WARNING, Gtk.ButtonsType.OK, text ); dlg.set_title( "TitleBar" ) res = dlg.run() dlg.destroy() return res if __name__ = = '__main__' : MessageBox.Show( "MessageBox.Show Test" ); |
まあコンパイルするわけだから実行速度的には Python を圧倒するわけだ。
こんな PyGI で書いているのとほとんど同じ感覚で C 言語で作られたのと同様な実効速度を持つアプリケーションが生成できるなのならば、それはとっても嬉しいなって。