26 June 2010

(Gtk2-Perl) 基本的な入力操作系ダイアログボックスの作成方法メモ

Gtk2-Perlライブラリを用いて、基本的なダイアログボックスの作成方法メモ。

・1行テキスト入力ダイアログボックス
・コンボボックスでの選択ダイアログボックス
・ファイル、ディレクトリ選択ダイアログボックス
・色の選択ダイアログボックス

■ 参考資料
Gtk2-Perl公式ページ
Gtk2-Perlライブラリのリファレンス
定数一覧はこちら(Gtk2::enums)
チュートリアル (Gtk2-Perl Study Guide)

■ 1行テキスト入力ダイアログボックス

こんな感じのものをイメージしている

20100626-gdk2-entry.png

以下、ソースコード


#!/usr/bin/perl

use strict;
use warnings;
use utf8;
use Gtk2 qw/-init/;
binmode( STDOUT, ":utf8" ); # "Wide character in print at ..." 警告を抑止

MainDialog();
exit;

sub MainDialog
{
my $strInput = ""; # ダイアログに渡す文字列(リファレンス)

my $window; # メインウインドウ
$window = Gtk2::Window->new('toplevel');
$window->signal_connect( "destroy" => sub { Gtk2::main_quit; } ); # ウインドウの閉じるボタンの処理
$window->set_title("Dialogのテスト(メインウインドウ)");
$window->set_border_width(5);

my $vbox = Gtk2::VBox->new();
$window->add($vbox);
my $label = Gtk2::Label->new("各種コントロールのテストをします");
$vbox->add($label);

# Entryのテスト
my $hbox = Gtk2::HBox->new();
$vbox->add($hbox);
my $entry = Gtk2::Entry->new();
$entry->set_text("サンプル文字列");
$entry->set_width_chars(30);
$hbox->add($entry);
my $button_opendlg = Gtk2::Button->new("Entry");
$button_opendlg->signal_connect("clicked" => sub {
$strInput = $entry->get_text();
if(InputDialog_Entry($window, \$strInput, "文字列を入力:" ) == '1')
{
$entry->set_text($strInput);
} else
{
$entry->set_text("Cancelが押されました");
}
}
);
$hbox->add($button_opendlg);

# 閉じるボタン
my $button_cancel = Gtk2::Button->new("プログラム終了");
$button_cancel->signal_connect("clicked" => sub { Gtk2->main_quit; });
$vbox->add($button_cancel);

$window->show_all();
Gtk2->main();

return(0);

}


sub InputDialog_Entry
{
my $window_main = shift; # 関数の引数(親ウインドウのハンドル)
my $ref_strInput = shift; # 関数の引数(参照渡し。テキストボックスの文字列を返す)
my $sMessage = shift; # 関数の引数(メッセージとして表示する文字列)
my $nResult = 0; # 戻り値(OK=1, Cancel=0)

my $dialog = Gtk2::Dialog->new("Entryコントロールのテスト", $window_main, ['destroy-with-parent'], 'gtk-cancel' => 'cancel', 'gtk-ok' => 'ok');

# 水平ボックスを、DialogのビルトインのVBoxの中に配置。
my $hbox = Gtk2::HBox->new();
$hbox->set_border_width(10); # コントロール周囲の余白設定
$dialog->vbox->add($hbox);

# プロンプト文字列とテキストボックスを水平に配置
my $label = Gtk2::Label->new($sMessage);
$hbox->add($label);
my $entry = Gtk2::Entry->new;
$entry->set_text($$ref_strInput);
$entry->set_width_chars(50);
$hbox->pack_start($entry, 0, 0, 0); # ダイアログの余白があっても自動拡張しない

$dialog->set_default_response ('ok');
$dialog->show_all();

# ダイアログの応答ループ
my $response = $dialog->run();
if($response eq 'ok')
{
$nResult = 1;
$$ref_strInput = $entry->get_text();
}
else{$nResult = 0;}

$dialog->destroy;
return($nResult);
}

■ コンボボックスでの選択ダイアログボックス

20100626-gdk2-combobox.png


#!/usr/bin/perl

use strict;
use warnings;
use utf8;
use Gtk2 qw/-init/;
binmode( STDOUT, ":utf8" ); # "Wide character in print at ..." 警告を抑止

MainDialog();
exit;

sub MainDialog
{
my $strInput = ""; # ダイアログに渡す文字列(リファレンス)

my $window; # メインウインドウ
$window = Gtk2::Window->new('toplevel');
$window->signal_connect( "destroy" => sub { Gtk2::main_quit; } ); # ウインドウの閉じるボタンの処理
$window->set_title("Dialogのテスト(メインウインドウ)");
$window->set_border_width(5);

my $vbox = Gtk2::VBox->new();
$window->add($vbox);
my $label = Gtk2::Label->new("各種コントロールのテストをします");
$vbox->add($label);


# ComboBoxのテスト
my $hbox = Gtk2::HBox->new();
$vbox->add($hbox);
my $entry = Gtk2::Entry->new();
$entry->set_text("サンプル文字列");
$entry->set_width_chars(30);
$hbox->add($entry);
my $button_opendlg = Gtk2::Button->new("ComboBox");
$button_opendlg->signal_connect("clicked" => sub {
$strInput = $entry->get_text();
if(InputDialog_ComboBox($window, \$strInput, "ひとつ選択:" ) == '1')
{
$entry->set_text($strInput);
} else
{
$entry->set_text("Cancelが押されました");
}
}
);
$hbox->add($button_opendlg);


# 閉じるボタン
my $button_cancel = Gtk2::Button->new("プログラム終了");
$button_cancel->signal_connect("clicked" => sub { Gtk2->main_quit; });
$vbox->add($button_cancel);

$window->show_all();
Gtk2->main();

return(0);

}

sub InputDialog_ComboBox
{
my $window_main = shift; # 関数の引数(親ウインドウのハンドル)
my $ref_strInput = shift; # 関数の引数(参照渡し。テキストボックスの文字列を返す)
my $sMessage = shift; # 関数の引数(メッセージとして表示する文字列)
my $nResult = 0; # 戻り値(OK=1, Cancel=0)

my $dialog = Gtk2::Dialog->new("ComboBoxコントロールのテスト", $window_main, ['destroy-with-parent'], 'gtk-cancel' => 'cancel', 'gtk-ok' => 'ok');

# 水平ボックスを、DialogのビルトインのVBoxの中に配置。
my $hbox = Gtk2::HBox->new();
$hbox->set_border_width(10); # コントロール周囲の余白設定
$dialog->vbox->add($hbox);

# プロンプト文字列とコンボボックスを水平に配置
my $label = Gtk2::Label->new($sMessage);
$hbox->add($label);
my $combobox = Gtk2::ComboBox->new_text();
$combobox->append_text("Windows");
$combobox->append_text("MacOS X");
$combobox->append_text("Linux");
$combobox->append_text("Free BSD");
$combobox->set_active(2);
$hbox->add($combobox);

$dialog->set_default_response ('ok');
$dialog->show_all();

# ダイアログの応答ループ
my $response = $dialog->run();
if($response eq 'ok')
{
$nResult = 1;
# $$ref_strInput = $combobox->get_active();
$$ref_strInput = $combobox->get_active_text();
}
else{$nResult = 0;}

$dialog->destroy;
return($nResult);

}


■ ファイル、ディレクトリ選択ダイアログボックス

20100626-gdk2-file.png


#!/usr/bin/perl

use strict;
use warnings;
use utf8;
use Gtk2 qw/-init/;
binmode( STDOUT, ":utf8" ); # "Wide character in print at ..." 警告を抑止

MainDialog();
exit;

sub MainDialog
{
my $strInput = ""; # ダイアログに渡す文字列(リファレンス)

my $window; # メインウインドウ
$window = Gtk2::Window->new('toplevel');
$window->signal_connect( "destroy" => sub { Gtk2::main_quit; } ); # ウインドウの閉じるボタンの処理
$window->set_title("Dialogのテスト(メインウインドウ)");
$window->set_border_width(5);

my $vbox = Gtk2::VBox->new();
$window->add($vbox);
my $label = Gtk2::Label->new("各種コントロールのテストをします");
$vbox->add($label);


# FileChooserDialog(open)のテスト(テキストボックスとボタンを水平配置する)
my $hbox_filechooser = Gtk2::HBox->new();
$vbox->add($hbox_filechooser);
my $entry_filechooser = Gtk2::Entry->new();
$entry_filechooser->set_text("/home");
$entry_filechooser->set_width_chars(30);
$hbox_filechooser->add($entry_filechooser);
my $button_opendlg_filechooser = Gtk2::Button->new("FileChooserDialog(open)");
$button_opendlg_filechooser->signal_connect("clicked" => sub {
$strInput = $entry_filechooser->get_text();
if(InputDialog_FileChooser($window, \$strInput, "open", "ファイルを選択してください" ) == '1')
{
$entry_filechooser->set_text($strInput);
} else
{
$entry_filechooser->set_text("Cancelが押されました");
}
}
);
$hbox_filechooser->add($button_opendlg_filechooser);

# FileChooserDialog(save)のテスト(テキストボックスとボタンを水平配置する)
my $hbox_filechooser2 = Gtk2::HBox->new();
$vbox->add($hbox_filechooser2);
my $entry_filechooser2 = Gtk2::Entry->new();
$entry_filechooser2->set_text("/home");
$entry_filechooser2->set_width_chars(30);
$hbox_filechooser2->add($entry_filechooser2);
my $button_opendlg_filechooser2 = Gtk2::Button->new("FileChooserDialog(save)");
$button_opendlg_filechooser2->signal_connect("clicked" => sub {
$strInput = $entry_filechooser2->get_text();
if(InputDialog_FileChooser($window, \$strInput, "save", "ファイルを選択してください" ) == '1')
{
$entry_filechooser2->set_text($strInput);
} else
{
$entry_filechooser2->set_text("Cancelが押されました");
}
}
);
$hbox_filechooser2->add($button_opendlg_filechooser2);

# FileChooserDialog(select-folder)のテスト(テキストボックスとボタンを水平配置する)
my $hbox_filechooser3 = Gtk2::HBox->new();
$vbox->add($hbox_filechooser3);
my $entry_filechooser3 = Gtk2::Entry->new();
$entry_filechooser3->set_text("/home");
$entry_filechooser3->set_width_chars(30);
$hbox_filechooser3->add($entry_filechooser3);
my $button_opendlg_filechooser3 = Gtk2::Button->new("FileChooserDialog(select-folder)");
$button_opendlg_filechooser3->signal_connect("clicked" => sub {
$strInput = $entry_filechooser3->get_text();
if(InputDialog_FileChooser($window, \$strInput, "select-folder", "ファイルを選択してください" ) == '1')
{
$entry_filechooser3->set_text($strInput);
} else
{
$entry_filechooser3->set_text("Cancelが押されました");
}
}
);
$hbox_filechooser3->add($button_opendlg_filechooser3);


# 閉じるボタン
my $button_cancel = Gtk2::Button->new("プログラム終了");
$button_cancel->signal_connect("clicked" => sub { Gtk2->main_quit; });
$vbox->add($button_cancel);

$window->show_all();
Gtk2->main();

return(0);

}


sub InputDialog_FileChooser
{
my $window_main = shift; # 関数の引数(親ウインドウのハンドル)
my $ref_strInput = shift; # 関数の引数(参照渡し。テキストボックスの文字列を返す)
my $strMode = shift; # 関数の引数(ダイアログのモード。open, save, select-folder, create-folderのいづれか)
my $sMessage = shift; # 関数の引数(メッセージとして表示する文字列)
my $nResult = 0; # 戻り値(OK=1, Cancel=0)

my $dialog = Gtk2::FileChooserDialog->new("FileChooserDialog(open)のテスト", $window_main, $strMode, 'gtk-cancel' => 'cancel', 'gtk-ok' => 'ok');
$dialog->set_current_folder($$ref_strInput);

if($strMode ne "select-folder" && $strMode ne "create-folder")
{
# ファイル表示のフィルタ
my $filter_text = Gtk2::FileFilter->new();
$filter_text->set_name("テキストファイル");
$filter_text->add_mime_type("text/*");
$dialog->add_filter($filter_text);

my $filter_all = Gtk2::FileFilter->new();
$filter_all->set_name("全てのファイル");
$filter_all->add_pattern("*");
$dialog->add_filter($filter_all);
}

# 保存モードの時は、「無題.txt」と表示する
if($strMode eq "save"){ $dialog->set_current_name("無題.txt"); }

# ダイアログの応答ループ
my $response = $dialog->run();
if($response eq 'ok')
{
$nResult = 1;
$$ref_strInput = $dialog->get_filename();
}
else{$nResult = 0;}

$dialog->destroy;
return($nResult);
}


■ 色の選択ダイアログボックス

20100626-gdk2-color.png


#!/usr/bin/perl

use strict;
use warnings;
use utf8;
use Gtk2 qw/-init/;
binmode( STDOUT, ":utf8" ); # "Wide character in print at ..." 警告を抑止

MainDialog();
exit;

sub MainDialog
{
my $strInput = ""; # ダイアログに渡す文字列(リファレンス)

my $window; # メインウインドウ
$window = Gtk2::Window->new('toplevel');
$window->signal_connect( "destroy" => sub { Gtk2::main_quit; } ); # ウインドウの閉じるボタンの処理
$window->set_title("Dialogのテスト(メインウインドウ)");
$window->set_border_width(5);

my $vbox = Gtk2::VBox->new();
$window->add($vbox);
my $label = Gtk2::Label->new("各種コントロールのテストをします");
$vbox->add($label);


# colorselectionDialogのテスト(テキストボックスとボタンを水平配置する)
my $hbox = Gtk2::HBox->new();
$vbox->add($hbox);
my $entry = Gtk2::Entry->new();
$entry->set_text("808080");
$entry->set_width_chars(30);
$hbox->add($entry);
my $button_opendlg = Gtk2::Button->new("ColorSelection");
$button_opendlg->signal_connect("clicked" => sub {
$strInput = $entry->get_text();
if(InputDialog_ColorSelection($window, \$strInput, "ファイルを選択してください" ) == '1')
{
$entry->set_text($strInput);
} else
{
$entry->set_text("Cancelが押されました");
}
}
);
$hbox->add($button_opendlg);


# 閉じるボタン
my $button_cancel = Gtk2::Button->new("プログラム終了");
$button_cancel->signal_connect("clicked" => sub { Gtk2->main_quit; });
$vbox->add($button_cancel);

$window->show_all();
Gtk2->main();

return(0);

}



sub InputDialog_ColorSelection
{
my $window_main = shift; # 関数の引数(親ウインドウのハンドル)
my $ref_strInput = shift; # 関数の引数(参照渡し。テキストボックスの文字列を返す)
my $sMessage = shift; # 関数の引数(メッセージとして表示する文字列)
my $nResult = 0; # 戻り値(OK=1, Cancel=0)

my $dialog = Gtk2::ColorSelectionDialog->new("ColorSelectionDialogのテスト");

my($r, $g, $b) = convert_hex_to_color($$ref_strInput);
my $color = Gtk2::Gdk::Color->new($r,$g,$b);
$dialog->colorsel->set_current_color($color);

$dialog->show_all();

# ダイアログの応答ループ
my $response = $dialog->run();
if($response eq 'ok')
{
$nResult = 1;
$color = $dialog->colorsel->get_current_color();
$$ref_strInput = sprintf("%02X%02X%02X", ($color->red /256), ($color->green /256), ($color->blue /256));
}
else{$nResult = 0;}

$dialog->destroy;
return($nResult);
}


sub convert_hex_to_color {
my ($colour) = @_;
my ($red, $green, $blue) = $colour =~ /(..)(..)(..)/;

$red = hex($red)*256;
$green = hex($green)*256;
$blue = hex($blue)*256;

return ($red, $green, $blue);
}