前回の GTK+ コードでコンパイル時に WARNING が出ていた件が解決した。
valac はオプションに -C を入れるとコンパイル前に C 言語に変換されたソースコードを吐き出す。
コレを利用してどのように変換されたかを調べる。
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
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 が渡ってくるようだ。
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 される。
エラーなんて絶対に起こらないし厳密すぎだしこんなの面倒くさいよ!
という場合は以下みたいな超手抜きコードでイケる。
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() を使いたい。
ということで簡易なものを作ってみた。
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 ではこんな感じ。
#!/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 言語で作られたのと同様な実効速度を持つアプリケーションが生成できるなのならば、それはとっても嬉しいなって。