prev Page / next

Gtk2-Perl을 사용한 크로스플랫폼 GUI 환경

by keedi (김도형)

Emstone Lab.

Seoul.pm

문서는 이곳에서도
볼 수 있습니다:

http://sorry.not.yet

What is GTK+?

G
T
K

Gimp
T
K

Gimp
Tool
K

Gimp
Tool
Kit

GTK+의 장점

GTK+의 장점

GTK+의 장점

GTK+의 장점

GTK+의 장점

GTK+의 장점

언어 바인딩

언어 바인딩

언어 바인딩

언어 바인딩

언어 바인딩

언어 바인딩

언어 바인딩

언어 바인딩

언어 바인딩

GTK+ 관련 Lib

GTK+ 관련 라이브러리

GTK+ 관련 라이브러리

GTK+ 관련 라이브러리

GTK+ 관련 라이브러리

GTK+ 관련 라이브러리

GTK+ 관련 라이브러리

GTK+ 관련 라이브러리

현재 GTK+ 버전

GTK+-2.0

현재 GTK+ 안정 버전

현재 GTK+ 개발 버전

우분투 Hardy의 GTK+ 버전

keedi@x40:~$ pkg-config --modversion glib-2.0
2.16.4
keedi@x40:~$ pkg-config --modversion gtk+-2.0
2.12.9
keedi@x40:~$

최신 소식은

http://www.gtk.org

GTK+ 공식 홈페이지

GTK+ 공식 홈페이지

GTK2-Perl 공식 홈페이지

http://gtk2-perl.sf.net/

GTK2-Perl 공식 홈페이지

GTK2-Perl 공식 홈페이지

GTK2-Perl 구성

GTK2-Perl 구성

GTK2-Perl 구성

GTK2-Perl 구성

GTK2-Perl 구성

GTK2-Perl 구성

GTK2-Perl 구성

GTK2-Perl 구성

Gtk2 in CPAN

Gtk2 in CPAN

Glib in CPAN

Glib in CPAN

Cairo in CPAN

Cairo in CPAN

Gtk2-Perl 설치

Gtk2-Perl 설치

Linux

패키지 관리자 이용

Ubuntu Linux

Ubuntu Linux에서 설치

Fedora Linux

Fedora Linux에서 설치

패키지 관리자를 이용하지 않는다면

CPAN을 이용한 설치

CPAN 이용시 필요한 파일

CPAN 이용시 필요한 파일 (contd.)

CPAN을 이용한 설치

keedi@x40:~$ sudo cpan Gtk2

MS Windows

MS Windows에서 설치

MS Windows에서 설치

MS Windows에서 설치

어려운 방법

Gtk2+ From Scratch!!

윈도우즈에 설치한 Perl을

컴파일한 컴파일러 필요

gtk.org에서 제공하는

윈도우즈용

Gtk+/Glib/Cairo 관련

개발용 파일(SDK) 설치

gtk.org에서 제공하는

바이너리 이외의

파일 및 유틸리티도 필요

Tor Lillqvist (tml)

Misc GIMP-related
packages for Windows

# Visit Here!
http://www.gimp.org/~tml/gimp/win32/downloads.html

tml's Misc GIMP-related packages

tml's Misc GIMP-related packages

쉬운 방법

쉬운 방법

쉬운 방법

쉬운 방법

쉬운 방법

Cygwin

Cygwin

Linux와 동일 :-)

ActivePerl

Paul의 ActiveState

저장소를 추가!

http://voltar.org/active/5.8/

Paul's ActiveState Repo

Paul's ActiveState Repo

# Paul's ActiveState 저장소를 추가하세요!
ppm rep add "Paul's Repo" http://voltar.org/active/5.8/

# Gtk2 설치
ppm install Gtk2

Camelbox

Camelbox 공식 홈페이지

http://code.google.com /p/camelbox/

Camelbox Home

Camelbox Home

위에서 언급한 다른 모든 방법은 잊어버리세요!

윈도우즈 사용자라면 Camelbox로 대동단결!

Camelbox 인스톨러

Camelbox 인스톨러

Why Camelbox is so special?

Why Camelbox is so special?

Why Camelbox is so special?

Why Camelbox is so special?

Why Camelbox is so special?

Why Camelbox is so special?

Camelbox의 특징

Camelbox의 특징

Camelbox의 특징

Camelbox의 특징

Camelbox의 특징

Camelbox의 특징

Camelbox의 특징

Camelbox의 특징

Camelbox의 특징 (contd.)

Camelbox의 특징 (contd.)

Camelbox의 특징 (contd.)

Camelbox의 특징 (contd.)

Camelbox의 특징 (contd.)

Camelbox의 특징 (contd.)

Camelbox가 설치하는 모듈

XML::Parser, YAML, LWP,
Moose, PAR, PAR::Packer,
JSON, Log::Log4perl,
Date::Format, Win32::API 등

Ok!

Finally we got Gtk2 & Gtk2-Perl!!

Hello World!?

Hello World!

#!/usr/bin/perl

use strict;
use warnings;

use Gtk2 -init;

#...

Hello World! (contd.)

#...

my $window = Gtk2::Window->new('toplevel');
my $button = Gtk2::Button->new('Hello World!');
$button->signal_connect(
    clicked => sub { Gtk2->main_quit }
);

$window->add($button);
$window->show_all;

Gtk2->main;

Run It

Run It!

$ ./hello-world.pl

use Gtk2 -init;

use Gtk2 -init;

use Gtk2 -init;

use Gtk2 -init;

use Gtk2 -init;

use Gtk2 -init;

Gtk2::Window

Gtk2::Window

GObject
 +----GInitiallyUnowned
       +----GtkObject
             +----GtkWidget
                   +----GtkContainer
                         +----GtkBin
                               +----GtkWindow

잠깐! 위젯 구조를 설명하는 이유?

위젯 구조를 설명하는 이유?

상속받은 자식 위젯은
부모 위젯의 메소드를
사용할 수 있다!

Gtk2::Window

Gtk2::Window

Gtk2::Window

Gtk2::Window

Gtk2::Window

Gtk2::Window

Gtk2::Window (contd.)

Gtk2::Window (contd.)

Gtk2::Window (contd.)

Gtk2::Window (contd.)

Gtk2::Window (contd.)

Gtk2::Button

Gtk2::Button

GObject
 +----GInitiallyUnowned
       +----GtkObject
             +----GtkWidget
                   +----GtkContainer
                         +----GtkBin
                               +----GtkButton

Gtk2::Button

Gtk2::Button

Gtk2::Button

Gtk2::Button

Gtk2::Button

Gtk2::Button

$button-> signal_connect()

$button->signal_connect()

$button->signal_connect()

$button->signal_connect()

$button->signal_connect()

$button->signal_connect()

$button->signal_connect()

$button->signal_connect() (contd.)

$button->signal_connect() (contd.)

$button->signal_connect() (contd.)

$button->signal_connect() (contd.)

$button->signal_connect() (contd.)

$button->signal_connect() (contd.)

$widget->signal_connect(
    event => \&event_handler,
    $user_data
);

$button->signal_connect(
    clicked => sub {
        warn "hi!\n"
    },
);

$button->signal_connect() (contd.)

$button->signal_connect() (contd.)

$button->signal_connect() (contd.)

$button->signal_connect() (contd.)

$button->signal_connect() (contd.)

$button->signal_connect() (contd.)

$button->signal_connect() (contd.)

이름공간과 객체

이름공간과 객체

C lib의 이름 공간은
펄의 패키지로 맵핑

이름공간과 객체

g_          => Glib
gtk_        => Gtk2
gdk_        => Gtk2::Gdk
gdk_pixbuf_ => Gtk2::Gdk::Pixbuf
pango_      => Gtk2::Pango

이름공간과 객체 (contd.)

GtkButton            => Gtk2::Button
GdkPixbuf            => Gtk2::Gdk::Pixbuf
GtkScrolledWindow    => Gtk2::ScrolledWindow
PangoFontDescription => Gtk2::Pango::FontDescription

이름공간과 객체 (contd.)

in C:
  GtkWidget * b;
  b = gtk_check_button_new_with_mnemonic("_Something");
  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(b), TRUE);
  gtk_widget_show(b);

in perl:
  my $b = Gtk2::CheckButton->new('_Something');
  $b->set_active(1);
  $b->show;

Win32 사용자를 위한 Tip!

Gtk2와 유니코드

Gtk2와 유니코드

Gtk2와 유니코드

Gtk2와 유니코드

Gtk2와 유니코드

Gtk2와 유니코드

Gtk2와 유니코드

Gtk2와 유니코드

Gtk2와 유니코드

한글 깨짐 해결방법

한글 깨짐 해결방법

한글 깨짐 해결방법

한글 깨짐 해결방법

한글 깨짐 해결방법

한글 깨짐 해결방법

한글 깨짐 해결방법

한글 깨짐 해결방법

Use Encode;

use Encode qw(decode);

my $DECODING = 'cp949';
sub _d { decode($DECODING, shift) }

# Gtk2::Button->new("눌러주세요!")
Gtk2::Button->new(_d("눌러주세요!"));

마지막 예제

경품!

(+_+)

mknametag.pl

#!/usr/bin/perl
use strict;
use warnings;

use GD;

die "Usage: $0 <no> <name> <type> > file.png\n"
    unless @ARGV >= 2;
my ( $no, $name, $type ) = @ARGV;

# create a new image
my $bg = newFromPng GD::Image('name-tag-template.png');
my $gd = new GD::Image( 283, 198 );

my $white = $gd->colorAllocate( 255, 255, 255 );
my $black = $gd->colorAllocate( 0,   0,   0 );
my $red   = $gd->colorAllocate( 255, 0,   0 );
my $blue  = $gd->colorAllocate( 0,   0,   255 );

$gd->transparent($white);
$gd->interlaced('true');
$gd->setAntiAliased($black);

if ( $type ) {
    $gd->stringFT(
        $black,
        '/home/moonpfe/.fonts/SeoulNamsanEB.ttf',
        25, 0, 20, 50,
        $type,
        {
            linespacing => 1.0,
            charmap     => 'Unicode',
        }
    );

    $gd->stringFT(
        $black,
        '/home/moonpfe/.fonts/SeoulNamsanEB.ttf',
        35, 0, 70, 105,
        $name,
        {
            linespacing => 1.0,
            charmap     => 'Unicode',
        }
    );
}
else {
    $gd->stringFT(
        $black,
        '/home/moonpfe/.fonts/SeoulNamsanEB.ttf',
        35, 0, 30, 80,
        $name,
        {
            linespacing => 1.0,
            charmap     => 'Unicode',
        }
    );
}

$gd->stringFT(
    $black,
    '/home/moonpfe/.fonts/SeoulNamsanEB.ttf',
    16, 0, 240, 30,
    $no,
    {
        linespacing => 1.0,
        charmap     => 'Unicode',
    }
);

binmode STDOUT;

$bg->copyResampled($gd, 0, 0, 0, 0, 283, 198, 283, 198);
print $bg->png;

gui.pl

#!/usr/bin/perl 

use strict;
use warnings;

use Encode qw(decode);
use Gtk2 -init;

my $DECODING = 'utf-8';
sub _d { decode($DECODING, shift) }

my %widget_of;

my $window = Gtk2::Window->new('toplevel');
$window->signal_connect(destroy => sub { Gtk2->main_quit });
$widget_of{window} = $window;

my $vbox = Gtk2::VBox->new(0, 5);

my ( $hbox, $label, $entry );

    $hbox = Gtk2::HBox->new(0, 5);
    $label = Gtk2::Label->new(_d('이름:'));
    $entry = Gtk2::Entry->new();
    $hbox->pack_start_defaults($label);
    $hbox->pack_start_defaults($entry);
    $vbox->pack_start_defaults($hbox);
    $widget_of{name} = $entry;

    $hbox = Gtk2::HBox->new(0, 5);
    $label = Gtk2::Label->new(_d('번호:'));
    $entry = Gtk2::Entry->new();
    $hbox->pack_start_defaults($label);
    $hbox->pack_start_defaults($entry);
    $vbox->pack_start_defaults($hbox);
    $widget_of{no} = $entry;

    $hbox = Gtk2::HBox->new(0, 5);
    $label = Gtk2::Label->new(_d('상태:'));
    $entry = Gtk2::Entry->new();
    $hbox->pack_start_defaults($label);
    $hbox->pack_start_defaults($entry);
    $vbox->pack_start_defaults($hbox);
    $widget_of{type} = $entry;

my $button;
    $hbox = Gtk2::HBox->new(0, 5);

    $button = Gtk2::Button->new(_d('초기화'));
    $button->signal_connect(clicked => \&reset_text_entry);
    $hbox->pack_start_defaults($button);

    $button = Gtk2::Button->new(_d('생성'));
    $button->signal_connect(clicked => \&generate_name_tag);
    $hbox->pack_start_defaults($button);

    $vbox->pack_start_defaults($hbox);

$window->add($vbox);
$window->show_all;

Gtk2->main;

sub reset_text_entry {
    my $self = shift;

    $widget_of{no}->set_text(q{});
    $widget_of{name}->set_text(q{});
    $widget_of{type}->set_text(q{});

    $widget_of{window}->set_focus($widget_of{name});
}

sub generate_name_tag {
    my $self = shift;

    my $no   = $widget_of{no}->get_text;
    my $name = $widget_of{name}->get_text;
    my $type = $widget_of{type}->get_text;

    print STDERR "$no - $name - $type\n";

    my $cmd = "./mknametag.pl '$no' '$name' '$type' > tmp.png\n";
    print STDERR $cmd;
    system $cmd;
    system 'eog tmp.png';
}

Gtk2-Perl을 빨리 익히기

Gtk2-Perl을 빨리 익히기

Gtk2-Perl을 빨리 익히기 (contd.)

알아두면 편리한 Gtk2-Perl 위젯

알아두면 편리한 Gtk2-Perl 위젯 (contd.)

The End.

Any Question?

Thank you!