Selama ini aku kerap menggunakan dialog, xdialog, gdialog, kdialog atau zenity untuk membina interface gui menggunakan bash.
Hari ini aku telah mencuba untuk menggunakan gtkdialog pula.
Gtkdialog nampaknya lebih memudahkan proses membina gui kerana ia menyokong glade. Tidak perlu bersusah payah untuk mengingat syntax gtk serta gui dapat dibina dengan cepat.
Secara asas untuk scripting bash menggunakan gtkdialog dan glade; terbahagi kepada 3 pecahan:
1. membina gui/interface file glade menggunakan glade2 atau glade3 2. membina executable bash untuk menghubungkan functions dan glade
3. membina functions yang mengandungi code code bash.
Kita tidak akan bincangkan bagaimana untuk membina file glade kerana ia straight forward menggunakan aplikasi glade.
Untuk bash executable, contoh adalah seperti berikut:
#! /bin/bash gtkdialog --glade-xml=myprogram.glade \ --include=myprogram.functions \ --program=window1 |
* myprogram.glade = glade file yang telah kita bina
* myprogram.functions = function file
* window1 = nama main window pada glade
Kebanyakan code scripting bash akan berada pada file functions. Bentuk file adalah seperti berikut:
#! /bin/bash
function nama_arahan() { code ....... xode } |
Ambil perhatian pada function "nama_arahan ".
Nama ini akan digunakan pada file glade untuk menjalankan code. Biasanya "nama_arahan" tadi kita gunakan pada "handler" glade misalnya pada button.
Di bawah adalah contoh bagaimana untuk membina interface login ke yahoo messenger melalui pidgin:
1. Glade file (ym.glade)
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*--> <!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
<glade-interface>
<widget class="GtkWindow" id="window1"> <property name="visible">True</property> <property name="title" translatable="yes">Yahoo Messenger</property> <property name="type">GTK_WINDOW_TOPLEVEL</property> <property name="window_position">GTK_WIN_POS_NONE</property> <property name="modal">False</property> <property name="default_width">300</property> <property name="default_height">150</property> <property name="resizable">True</property> <property name="destroy_with_parent">False</property> <property name="decorated">True</property> <property name="skip_taskbar_hint">False</property> <property name="skip_pager_hint">False</property> <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property> <property name="gravity">GDK_GRAVITY_NORTH_WEST</property> <property name="focus_on_map">True</property> <property name="urgency_hint">False</property> <property name="icon">/usr/share/pixmaps/pidgin/protocols/22/yahoo.png</property>
<child> <widget class="GtkVBox" id="vbox1"> <property name="visible">True</property> <property name="homogeneous">False</property> <property name="spacing">0</property>
<child> <widget class="GtkHBox" id="hbox2"> <property name="visible">True</property> <property name="homogeneous">False</property> <property name="spacing">0</property>
<child> <widget class="GtkImage" id="image1"> <property name="visible">True</property> <property name="pixbuf">/usr/share/pixmaps/pidgin/protocols/22/yahoo.png</property> <property name="xalign">0.5</property> <property name="yalign">0.5</property> <property name="xpad">38</property> <property name="ypad">0</property> </widget> <packing> <property name="padding">0</property> <property name="expand">False</property> <property name="fill">False</property> </packing> </child>
<child> <widget class="GtkLabel" id="label5"> <property name="visible">True</property> <property name="label" translatable="yes"><span foreground="red" size="large" style="italic" weight="bold">Yahoo Messenger Login</span></property> <property name="use_underline">False</property> <property name="use_markup">True</property> <property name="justify">GTK_JUSTIFY_CENTER</property> <property name="wrap">False</property> <property name="selectable">False</property> <property name="xalign">0.5</property> <property name="yalign">0.5</property> <property name="xpad">0</property> <property name="ypad">0</property> <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> <property name="width_chars">-1</property> <property name="single_line_mode">False</property> <property name="angle">0</property> </widget> <packing> <property name="padding">0</property> <property name="expand">False</property> <property name="fill">False</property> </packing> </child> </widget> <packing> <property name="padding">0</property> <property name="expand">False</property> <property name="fill">False</property> </packing> </child>
<child> <widget class="GtkFixed" id="fixed1"> <property name="width_request">350</property> <property name="height_request">130</property> <property name="visible">True</property>
<child> <widget class="GtkEntry" id="username"> <property name="width_request">160</property> <property name="height_request">24</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="editable">True</property> <property name="visibility">True</property> <property name="max_length">0</property> <property name="text" translatable="yes"></property> <property name="has_frame">True</property> <property name="invisible_char">●</property> <property name="activates_default">False</property> </widget> <packing> <property name="x">152</property> <property name="y">16</property> </packing> </child>
<child> <widget class="GtkEntry" id="password"> <property name="width_request">160</property> <property name="height_request">24</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="editable">True</property> <property name="visibility">False</property> <property name="max_length">0</property> <property name="text" translatable="yes"></property> <property name="has_frame">True</property> <property name="invisible_char">*</property> <property name="activates_default">False</property> </widget> <packing> <property name="x">152</property> <property name="y">48</property> </packing> </child>
<child> <widget class="GtkLabel" id="label3"> <property name="width_request">104</property> <property name="height_request">24</property> <property name="visible">True</property> <property name="label" translatable="yes">Login Password :</property> <property name="use_underline">False</property> <property name="use_markup">False</property> <property name="justify">GTK_JUSTIFY_LEFT</property> <property name="wrap">False</property> <property name="selectable">False</property> <property name="xalign">0.5</property> <property name="yalign">0.5</property> <property name="xpad">0</property> <property name="ypad">0</property> <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> <property name="width_chars">-1</property> <property name="single_line_mode">False</property> <property name="angle">0</property> </widget> <packing> <property name="x">16</property> <property name="y">48</property> </packing> </child>
<child> <widget class="GtkLabel" id="label2"> <property name="width_request">104</property> <property name="height_request">24</property> <property name="visible">True</property> <property name="label" translatable="yes">Login Username :</property> <property name="use_underline">False</property> <property name="use_markup">False</property> <property name="justify">GTK_JUSTIFY_LEFT</property> <property name="wrap">False</property> <property name="selectable">False</property> <property name="xalign">0.5</property> <property name="yalign">0.5</property> <property name="xpad">0</property> <property name="ypad">0</property> <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> <property name="width_chars">-1</property> <property name="single_line_mode">False</property> <property name="angle">0</property> </widget> <packing> <property name="x">16</property> <property name="y">16</property> </packing> </child>
<child> <widget class="GtkLabel" id="label4"> <property name="width_request">37</property> <property name="height_request">16</property> <property name="visible">True</property> <property name="label" translatable="yes"></property> <property name="use_underline">False</property> <property name="use_markup">False</property> <property name="justify">GTK_JUSTIFY_LEFT</property> <property name="wrap">False</property> <property name="selectable">False</property> <property name="xalign">0.5</property> <property name="yalign">0.5</property> <property name="xpad">0</property> <property name="ypad">0</property> <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property> <property name="width_chars">-1</property> <property name="single_line_mode">False</property> <property name="angle">0</property> </widget> <packing> <property name="x">144</property> <property name="y">0</property> </packing> </child>
<child> <widget class="GtkButton" id="button2"> <property name="width_request">80</property> <property name="height_request">32</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="label">gtk-cancel</property> <property name="use_stock">True</property> <property name="relief">GTK_RELIEF_NORMAL</property> <property name="focus_on_click">True</property> <signal name="clicked" handler="exit:Cancel" last_modification_time="Thu, 19 Nov 2009 02:25:38 GMT"/> </widget> <packing> <property name="x">140</property> <property name="y">88</property> </packing> </child>
<child> <widget class="GtkButton" id="button3"> <property name="width_request">80</property> <property name="height_request">32</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="label">gtk-apply</property> <property name="use_stock">True</property> <property name="relief">GTK_RELIEF_NORMAL</property> <property name="focus_on_click">True</property> <signal name="clicked" handler="login_yahoo &quot;$username&quot; &quot;$password&quot;" last_modification_time="Thu, 19 Nov 2009 02:41:11 GMT"/> <signal name="released" handler="exit:Abort"/> </widget> <packing> <property name="x">230</property> <property name="y">88</property> </packing> </child> </widget> <packing> <property name="padding">0</property> <property name="expand">True</property> <property name="fill">True</property> </packing> </child> </widget> </child> </widget>
</glade-interface>
|
*<signal name="clicked" handler="login_yahoo &quot;$username&quot; &quot;$password&quot;"
Ini adalah bahagian dimana function login_yahoo digunakan sebagai handler apabila button3 di klik.
2. File functions (ym.functions)
#!/bin/sh # pidgin login dialog window # gtkdialog + glade by mambang # GPL # kill remaining pidgin process killall -9 pidgin
function login_yahoo() { NAME=$username PASSWD=$password rm -rf ~/.purple mkdir ~/.purple && chmod go-rwx ~/.purple cat<<EOF>~/.purple/accounts.xml <?xml version='1.0' encoding='UTF-8' ?> <account version='1.0'> <account> <protocol>prpl-yahoo</protocol> <name>yahoouser</name> <password>yahoopassword</password> <settings ui='gtk-gaim'> <setting name='auto-login' type='bool'>1</setting> </settings> <settings ui='gnt-purple'> <setting name='auto-login' type='bool'>1</setting> </settings> </account> </account> EOF perl -p -i -e "s/yahoouser/$NAME/g" ~/.purple/*.xml perl -p -i -e "s/yahoopassword/$PASSWD/g" ~/.purple/accounts.xml pidgin rm -rf ~/.purple exit 1 }
|
*function login_yahoo()
Function ini telah diguna pada handler clicked button3 pada glade.
*NAME=$username diperolehi daripada <widget class="GtkEntry" id="username">
*PASSWD=$password diperolehi daripada <widget class="GtkEntry" id="username">
Selebihnya adalah code biasa yang tidak bergantung kepada file glade.
3. Excutable bash (ym.sh)
#! /bin/bash gtkdialog --glade-xml=ym.glade \ --include=ym.functions \ --program=window1 |
*Telah diterangkan sebelum ini.
Anda akan dapat hasil sebegini apabila anda run ym.sh:
Selamat mencuba.