Aplikasi Gnome Sederhana Menggunakan libglade dan C / GTK +
Tutorial ini ditujukan bagi orang-orang yang tertarik untuk memulai mengembangkan aplikasi Gnome menggunakan GTK +.
Secara khusus, ia menggunakan Desainer Antarmuka Glade untuk membangun
antarmuka pengguna dan C / GTK + untuk menulis kode untuk aplikasi
Gnome. Aplikasi hanya akan menjadi jendela dengan bilah alat dan bilah status khas. Aplikasi ini akan digunakan dalam tutorial selanjutnya untuk menunjukkan berbagai aspek lain dari pemrograman Gnome.
Mari Memulai
Untuk keperluan tutorial ini, saya akan membangun proyek ini di sistem saya di / home / mcarrick / Projects / gnome3 / . Semua tangkapan layar dan buka / simpan lokasi akan mencerminkan lokasi itu. Ketika membahas hierarki jalur, saya akan membicarakannya relatif terhadap jalur itu. Sebagai contoh, menempatkan kode sumber di direktori / src berarti bahwa itu sebenarnya di direktori / home / mcarrick / Projects / gnome3 / src . Oke? Baik. Jadi Anda seharusnya membuat direktori 'gnome3' di suatu tempat dan direktori 'src' di dalam direktori itu.
Proyek yang akan kami bangun adalah giong untuk disebut 'gnome3', dan hanya aplikasi dasar Gnome. '3' berasal dari kenyataan bahwa saya sudah memiliki gnome1 dan gnome2 dari beberapa tutorial yang lebih lama.
Membangun Antarmuka di Glade
Perancang Antarmuka Glade, atau hanya Glade, adalah aplikasi Gnome yang memungkinkan kita untuk menata letak widget kita secara visual daripada melalui kode C. Apa widget itu? Widget mirip "objek" dalam kosakata berorientasi objek. Hanya sebagian besar widget di GTK + yang terlihat secara fisik. Dalam pemrograman Windows, kita mungkin menyebutnya "kontrol".
Tombol adalah widget, label pada tombol itu adalah widget lain, jendela
adalah widget, bilah gulir adalah widget, dll. Widget, seperti objek
atau kelas, dapat diturunkan dari widget lain. Widget jendela dapat berasal dari widget basis wadah, dll. Hubungan ini dikenal sebagai widget atau hierarki objek.
Jadi mari kita lihat apa yang saya bicarakan. Mulai Glade dan pilih 'Baru' dari menu 'Proyek', lalu klik tombol 'Proyek GNOME Baru'. Sekarang, sebelum kita melangkah lebih jauh, mari kita buat windows kita terlihat. Kita akan belajar apa yang mereka lakukan saat tutorial berjalan. Untuk saat ini, pastikan Anda membuka jendela Pallette, Editor Properti , dan Widget Tree . Anda dapat melakukannya dari menu 'Lihat' di jendela Glade utama.
Kami akan menambahkan Jendela Aplikasi Gnome ke proyek kami dengan mengklik ikon yang terletak di bilah alat Glade di bawah 'Gnome'. Sebuah jendela akan muncul. Itu adalah Jendela Aplikasi Gnome dan jendela utama untuk aplikasi kita. Jendela Aplikasi Gnome sebenarnya adalah widget GnomeApp, bagian dari libgnomeui.
Dokumentasi API menyatakan: "Widget GnomeApp dan fungsi terkait
menyediakan cara termudah untuk membuat aplikasi GNOME yang hampir
lengkap di libgnomeui". Itu sangat benar. Ini adalah cara yang sangat mudah untuk mengatur basis aplikasi Gnome. Sekarang kembali ke berbicara tentang widget dan hierarki objek, hierarki objek untuk widget GnomeApp ditunjukkan di bawah ini.
GObject
+ ---- GtkObject
+ ---- GtkWidget
+ ---- GtkContainer
+ ---- GtkBin
+ ---- GtkWindow
+ ---- GnomeApp

Seperti yang bisa kita lihat, GnomeApp diturunkan dari GtkWindow, dan seterusnya pohon. Di atas pohon adalah GObject yang merupakan objek dasar untuk semua objek lainnya. Ini adalah bagian dari glib (inti, fungsi dan utilitas tingkat rendah di dasar Gnome dan GTK). Awalannya adalah 'G'. Mulai sekarang, kaitkan satu 'g' dengan glib. Objek yang dimulai dengan 'G' dan fungsi yang dimulai dengan 'g_' biasanya akan dikaitkan dengan glib. Kemudian, kami memiliki beberapa objek dengan awalan "Gtk". Itu adalah bagian dari GTK. Objek yang dimulai dengan 'Gtk' dan fungsi yang dimulai dengan 'gtk_' biasanya dikaitkan dengan GTK +. Dan akhirnya, GnomeApp memiliki 'Gnome' sebagai awalan. Ini adalah bagian dari perpustakaan Gnome UI. Objek yang dimulai dengan 'Gnome' dan fungsi yang dimulai dengan 'gnome_' dikaitkan dengan pustaka Gnome.
Ini akan menjadi sangat jelas ketika Anda mulai menulis kode nanti di
tutorial. Kembali ke Glade, kita akan mengganti nama widget GnomeApp
menjadi sesuatu yang lebih bagus dan memberikannya judul, yang muncul di
"titlebar" jendela.
Untuk mengganti nama widget, klik untuk memilih 'app1' di jendela utama
Glade atau jendela Tree Widget, dan ubah properti 'Name:' di jendela Properties Glade menjadi 'app_window'. Juga ubah properti 'Judul' di jendela Properti Glade ke 'Gnome Application 3'. Di bawah ini adalah tangkapan layar dari sistem saya.

Sebelum kita melangkah lebih jauh, mari kita simpan file glade (file XML). Klik ikon 'Simpan'. Dalam dialog simpan, kita akan menyimpan file sebagai src / gnome3.glade.
Glade dapat menghasilkan kode sumber C atau C ++ yang mengkompilasi
untuk membangun aplikasi yang Anda desain, namun metode itu bukan lagi
cara ideal untuk menggunakan Glade. Sebagai gantinya, file proyek Glade, file .glade, diuraikan oleh aplikasi saat run-time menggunakan libglade.
Ini memungkinkan Anda untuk memodifikasi / memperbarui UI tanpa harus
mengkompilasi ulang seluruh program dan memungkinkan program terpisah
dari antarmuka. Jadi, saat menyimpan, satu-satunya hal yang benar-benar kami perhatikan adalah nama dan lokasi file 'Proyek'. Kami tidak akan membiarkan Glade membuat kode sehingga parameter lainnya tidak relevan untuk tutorial ini. Tangkapan layar saya di bawah.
Sekarang hanya ada satu hal lagi yang harus dilakukan dalam glade. Kita akan melampirkan penangan ke sinyal 'diklik' tombol bilah alat 'Baru'. Sinyal dapat dianggap sebagai peristiwa yang terjadi.
Sebagian besar objek memiliki berbagai sinyal yang mereka "pancarkan"
untuk berbagai peristiwa dan mereka juga mewarisi sinyal objek dasar di
sana. Anda dapat mengetahui sinyal apa yang dimiliki objek dengan merujuk ke dokumentasi API untuk objek itu. Pawang untuk sinyal, adalah fungsi callback, dan dipanggil ketika sinyal itu "dipancarkan".
Klik tombol 'toolbar_new' untuk memilihnya, dan kemudian beralih ke tab 'Sinyal' di jendela Properties di Glade. Kemudian di bagian bawah jendela, ada kotak berlabel 'Sinyal:'. Klik di kotak untuk menampilkan dialog Select Signal . Anda dapat memilih salah satu sinyal yang terkait dengan widget GtkToolButton atau widget dari mana ia berasal. Pilih sinyal 'diklik' dan klik tombol 'Oke'. Sekarang kembali ke jendela Properties, kotak 'Handler:' telah diisi dengan "on_toolbutton_new_clicked". Kita akan membiarkan itu apa adanya. Klik tombol 'Tambah' di bagian bawah jendela untuk menerapkan perubahan ini. Jendela Anda akan terlihat seperti milik saya di bawah ini.
"on_toolbutton_new_clicked" adalah nama fungsi yang perlu kita tulis
yang akan dipanggil ketika tombol bilah alat 'Baru' diklik.
Menulis Kode
Di sinilah kesenangan dimulai. Buka editor teks Anda dan buat src / main.c. Kita akan melangkah melalui kode ini bagian satu per satu mulai dari atas.
1: / * file config.h dihasilkan oleh autotools * /
2: #ifdef HAVE_CONFIG_H
3: # include & lt; config.h & gt;
4: #endif <span style = "color: # b59000"> <span style = "color: # 000000"> </span>
</span>
Bagian ini memiliki beberapa arahan preprocessor untuk menyertakan file yang disebut config.h. File config.h dihasilkan oleh program yang disebut 'autoheader' yang merupakan bagian dari GNU 'autotools'. Meskipun 'autotools' adalah bagian penting dari pengembangan aplikasi Gnome, itu di luar ruang lingkup dokumen ini.
6: / * ini akan menahan path ke file glade setelah "make install" * /
7: #define GLADE_FILE PACKAGE_DATA_DIR "/gnome3/gnome3.glade" <span style = "color: # b59000"> <span style = "color: # 000000"> </span> </span>
Di sini kita mendefinisikan path ke file XML gnome3.glade kami. PACKAGE_DATA_DIR didefinisikan dalam Makefile yang dihasilkan oleh autotools dan bergantung pada platform.
Pada sistem Fedora saya, PACKAGE_DATA_DIR akhirnya menjadi / usr /
local / share / dan dengan demikian, setelah mengkompilasi dan
menginstal aplikasi ini pada sistem saya (menggunakan perintah make
install), file glade untuk aplikasi ini akan berlokasi di / usr / local
/share/gnome3/gnome3.glade.
9: #termasuk & lt; gnome.h & gt;
10: #include & lt; glade / glade.h & gt; <span style = "color: # b59000"> <span style = "color: # 000000"> </span> </span>
Ini termasuk harus terlihat cukup jelas, namun, saya ingin menunjukkan satu hal kecil. File header yang disertakan akan memanggil pustaka dari mana mereka berasal.
Dalam hal ini, gnome.h akan memanggil gtk.h yang akan memanggil glib.h
dll. Jadi tidak perlu menyertakan gtk / gtk.h untuk aplikasi Gnome.
Glade / glade.h termasuk untuk libglade yang memungkinkan kita untuk menghasilkan antarmuka pengguna dari file XML glade.
12: / * prototipe fungsi panggilan balik * /
13: static gint delete_event_cb (GtkWidget * w, GdkEventAny * e, data gpointer);
14: static gint destroy_cb (GtkWidget * w, GdkEventAny * e, data gpointer); <span style = "color: # b59000"> <span style = "color: # 000000"> </span> </span> <span style = "color: # b59000"> <span style = "color: # 000000"> </span> </span> <span style = "color: # b59000"> </span>
Kedua baris ini menyatakan fungsi "callback", itulah sebabnya saya menambahkan akhiran '_cb' ke nama mereka. Ini akan "terhubung" ke sinyal. Saya akan berhenti di situ untuk saat ini, kita akan melihat ini lagi di kode.
17: int main (int argc, char * argv [])
18: {
19: GtkWidget * app_window; / * widget jendela aplikasi utama * /
20: GladeXML * gxml; / * glade file xml * /
Ketika kami meletakkan antarmuka kami di bagian sebelumnya, saya menunjukkan konvensi penamaan yang digunakan dengan widget. Kita melihatnya lagi di sini di mana kita mendeklarasikan dua variabel. Pertama, app_window adalah pointer ke tipe GtkWidget. Perhatikan awalan 'Gtk'. Karena itu, tipe GtkWidget adalah bagian dari pustaka GTK. Baris berikutnya kita mendeklarasikan gxml sebagai pointer ke tipe GladeXML. Ini harus menjadi bagian dari pustaka Glade, atau libglade.
Pada awalnya Anda mungkin bertanya mengapa kami mendeklarasikan app_window sebagai GtkWidget dan bukan GnomeApp. Inilah hierarki objek itu lagi. Ingatlah bahwa GnomeApp berasal dari beberapa objek yang kembali ke GtkWidget dan akhirnya kembali ke GObject. Jadi, widget GnomeApp adalah GtkWidget, dan dalam hal ini, itu adalah GObject. GtkWidget adalah objek dasar dari semua widget, dan memiliki fungsi yang sama untuk semua widget.
Misalnya ada fungsi untuk menampilkan widget yang disebut
gtk_widget_show () yang mengambil pointer ke GtkWidget sebagai
parameter. Karena itu kami biasanya mendeklarasikan widget sebagai kelas objek dasar mereka, sebuah GtkWidget.
Jadi sekarang kita memiliki app_window yang akan mereferensikan widget
GnomeApp kita (tetapi belum) dan kita memiliki gxml yang mereferensikan
objek GladeXML yang akan kita gunakan untuk membangun antarmuka dari
file XML Glade.
22: / * inisialisasi libgnome * /
23: gnome_program_init (PAKET, VERSI, LIBGNOMEUI_MODULE,
24: argc, argv,
25: NULL); <span style = "font-family: monospace"> </span> <span style = "color: # b59000"> <span style = "color: # 000000">
</span> </span> <span style = "font-family: monospace"> </span>
Semua aplikasi GTK + dan Gnome harus memanggil fungsi untuk menginisialisasi perpustakaan sebelum fungsi GTK + digunakan. Dalam program GTK + murni, Anda akan melihat gtk_init (). Fungsi ini, gnome_program_init () khusus untuk aplikasi Gnome.
Banyak kode yang Anda lihat, terutama dalam tutorial, Anda akan melihat
gnome_init () sebagai gantinya - yang sebenarnya terlihat lebih bagus
karena tidak memiliki semua argumen yang diteruskan ke sana. Namun, gnome_init () adalah fungsi yang sudah usang dan tidak boleh digunakan. Anda harus membaca tentang gnome_program_init () dalam dokumentasi API.
Anda pasti perlu tahu tentang fungsi ini, untuk saat ini, saya hanya
akan menjelaskan secara singkat seperti yang berlaku untuk program ini.
PAKET dan VERSI didefinisikan dalam file config.h yang secara otomatis dibuat oleh autotools. Untuk program ini, mereka masing-masing 'gnome3' dan '0,1'.
LIBGNOMEUI_MODULE didefinisikan dalam libgnomeui.h (yang telah kami
sertakan secara tidak langsung dengan memasukkan gnome.h) dan merupakan
modul yang berisi informasi untuk menginisialisasi pustaka gnome. argc dan argv adalah argumen baris perintah aplikasi C / C ++ standar yang kita kenal dan sukai. argc adalah hitungan argumen baris perintah dan argv adalah array string argumen baris perintah. Selanjutnya, fungsi mengambil serangkaian pasangan nama / nilai atribut yang diakhiri oleh NULL. Untuk menjaga hal-hal sederhana dan minimal untuk saat ini, kami hanya melewati penghentian NULL. (Daftar pasangan nama / nilai atribut kosong).
Dalam banyak tutorial dan kode yang Anda lihat menggunakan libglade,
Anda akan sering menemukan panggilan ke glade_init () pada saat ini
untuk menginisialisasi pustaka Glade (libglade). Ini bukan lagi panggilan yang diperlukan karena versi baru pustaka Glade akan diinisialisasi berdasarkan permintaan.
27: / * membuat objek GladeXML dan menghubungkan sinyal * /
28: gxml = glade_xml_new (GLADE_FILE, NULL, NULL);
29: glade_xml_signal_autoconnect (gxml); <span style = "font-family: monospace">
</span> <span style = "font-family: monospace"> </span>
Di sinilah kami menggunakan libglade untuk membangun antarmuka kami dari file XML Glade yang kami buat sebelumnya.
Jika Anda terbiasa dengan bahasa OOP (kelas) maka Anda terbiasa dengan
instantiate objek yang sering menggunakan kata kunci seperti "baru" (obj
= new SomeObject;). C secara teknis bukan bahasa berorientasi objek, namun, GTK + berbasis objek. Ini dicapai menggunakan fungsi.
Dengan sebagian besar objek GTK + akan ada serangkaian fungsi untuk
membuat yang baru dari objek-objek itu, seperti konstruktor kelas.
Panggilan ke glade_xml_new menciptakan objek GladeXML baru yang dirujuk
oleh gxml, dan itu juga menciptakan semua widget dalam file Glade yang
kami lewatkan ke fungsi sebagai argumen pertama (kami mendefinisikan
GLADE_FILE pada baris 7). Kami melewati NULL sebagai dua parameter lainnya karena kami belum perlu mengkhawatirkannya. Satu digunakan jika kita hanya ingin membangun widget tertentu dalam file glade dan yang lainnya digunakan untuk terjemahan.
Panggilan ke glade_xml_signal_autoconnect () adalah variasi pada fungsi lain, glade_xml_signal_connecr ().
Seperti namanya, fungsi "autoconnect" secara otomatis "menghubungkan"
sinyal yang ditentukan dalam file glade ke fungsi callback mereka
(sinyal "handler") dalam kode C.
Ingat ketika membangun antarmuka kami, kami menetapkan bahwa sinyal
"diklik" tombol bilah alat harus "ditangani" oleh fungsi
on_toolbar_new_clicked (). Panggilan ini membaca informasi itu dari file glade dan "menghubungkan" sinyal itu ke fungsi panggilan balik itu.
31: / * dapatkan app_window dari file XML glade * /
32: app_window = glade_xml_get_widget (gxml, "app_window");
Sekarang, semuanya bagus dan keren bahwa libglade dapat "membangun"
antarmuka kita dari file XML itu, tetapi bagaimana kita mereferensikan
widget itu?
Jawabannya adalah glade_xml_get_widget (), di mana 2 parameternya
adalah objek GladeXML gxml dan nama widget yang ingin kita "dapatkan". Dalam hal ini, kita mendapatkan "app_window" yang merupakan widget GnomeApp kami. Setelah panggilan ini, pointer GtkWidget app_window merujuk widget GnomeApp. Kami akan menggunakan ini beberapa baris nanti.
34: / * Hubungkan sinyal untuk penghentian aplikasi * /
35: g_signal_connect (G_OBJECT (app_window), "delete_event",
36: G_CALLBACK (delete_event_cb), NULL);
37:
38: g_signal_connect (G_OBJECT (app_window), "menghancurkan",
39: G_CALLBACK (destroy_cb), NULL);
Parameter ketiga dalam fungsi g_signal_connect () adalah fungsi yang kami sambungkan ke sinyal. Ini adalah fungsi "callback". Pertama-tama kita harus melemparkan fungsi ke dalam penunjuk GCallback menggunakan makro G_CALLBACK.
Dan akhirnya kami memiliki parameter ke-4 yang merupakan data yang akan
kami sampaikan ke fungsi panggilan balik kami, dalam hal ini, tidak ada
(NULL).
Artinya, ketika sinyal "delete_event" dipancarkan, fungsi kami yang bernama delete_event_cb () akan dipanggil. Ketika sinyal "hancurkan" dipancarkan, fungsi kami destroy_cb () akan dipanggil.
41: / * tampilkan jendela uta
Kedua garis ini juga "menghubungkan" sinyal ke fungsi yang "menangani" peristiwa itu.
Kita dapat mengatur ini di Glade seperti yang kita lakukan dengan
sinyal "klik" untuk tombol tool dan membiarkan fungsi
glade_xml_autoconnect () menghubungkan sinyal, namun, saya ingin
melakukannya di sini dalam kode sebagai demonstrasi bagaimana sinyal
terhubung dan menunjukkan beberapa casting macro. Sangat penting untuk memahami konsep sinyal dan fungsi panggilan balik. Ada 4 argumen yang diteruskan ke panggilan fungsi g_signal_connect ().
Pertama, G_OBJECT (app_window), yang merupakan app_window GtkWidget kami dilemparkan ke dalam pointer GObject. G_OBJECT adalah makro yang melakukan casting. Anda akan menemukan makro casting ini tersedia untuk semua casting yang perlu Anda lakukan.
G_signal_connect mengambil pointer GObject sebagai argumen pertama,
namun app_window kami didefinisikan sebagai pointer GtkWidget, itulah
sebabnya kita harus melemparkannya ketika meneruskannya sebagai
parameter. Ingatlah bahwa GtkWidget diturunkan dari GObject, itulah sebabnya kita bisa melemparkannya ke dalam pointer GObject. Contoh lain, adalah jika kita memiliki fungsi yang membutuhkan GtkWindow seperti gtk_window_get_title (). Kita bisa memasukkan app_window ke dalam penunjuk objek GtkWindow menggunakan makro GTK_WINDOW. Di sinilah hirarki objek itu sangat keren.
Kita dapat menggunakan fungsi-fungsi untuk kelas mana pun dari mana
widget diturunkan dengan melemparkan widget poitner ke tipe yang sesuai.
Parameter kedua dalam fungsi g_signal_connect () adalah nama sinyal yang digunakan untuk menghubungkan fungsi. Seperti yang Anda lihat, kami memiliki 2 sinyal yang kami hubungkan dengan fungsi. Yang pertama adalah sinyal "delete_event" yang dipancarkan ketika kami meminta agar jendela ditutup. Mengklik 'x' kecil di bagian atas jendela akan memunculkan sinyal ini. Berikutnya adalah sinyal "hancurkan" yang dipancarkan ketika jendela dihancurkan. Kita akan lihat mengapa ini penting nanti.
ma * /
42: gtk_widget_show (app_window);
Sekarang kita siap untuk benar-benar menunjukkan jendela kita. Fungsi gtk_widget_show () menunjukkan widget. Kami cukup memberikannya pointer GtkWidget kami, app_window yang merujuk widget GnomeApp kami - jendela aplikasi utama.
44: / * memulai loop GTK utama * /
45: gtk_main ();
46:
47: return 0;
48:}
Sekarang, fungsi gtk_main () adalah loop "tanpa akhir". Loop akan memanggil fungsi kami berdasarkan "peristiwa" yang terjadi. Contoh sempurna, adalah sinyal "klik" yang kami siapkan untuk tombol alat.
Ketika tombol itu diklik, loop gtk_main () menyerahkan kontrol ke
"handler" kami di_toolbutton_new_clicked () setelah itu kontrol
dilanjutkan di loop tanpa akhir. Ini adalah bagaimana kami mencapai aplikasi berbasis "event".
Untuk keluar dari loop, salah satu fungsi kami harus memanggil
gtk_main_quit (), itulah sebabnya kami memiliki panggilan balik untuk
sinyal "hancurkan" seperti yang akan kita lihat sebentar lagi.
50: static gint delete_event_cb (GtkWidget * w, GdkEventAny * e, data gpointer)
51: {
52: / * panggilan balik untuk sinyal "hapus" * /
53: g_print ("main.c: delete_event_cb () n");
54: return 0;
55:}
56:
57: static gint destroy_cb (GtkWidget * w, GdkEventAny * e, data gpointer)
58: {
59: / * panggilan balik untuk sinyal "hancurkan" * /
60: g_print ("main.c: destroy_event_cb () n");
61:
62: / * keluar dari aplikasi * /
63: gtk_main_quit ();
64: return 0;
65:}
Kami sebenarnya tidak perlu menangani "delete-event" untuk aplikasi
ini, namun, saya menambahkannya untuk menunjukkan kapan peristiwa itu
terjadi.
Baik delete_event_cb () dan destr_cb () saya memanggil g_print () (yang
sangat mirip dengan fungsi printf) untuk mencetak nama fungsi. Ini hanya supaya kita bisa melihat peristiwa ini terjadi. Namun perhatikan, pawang untuk sinyal "hancurkan" memiliki panggilan ke gtk_main_quit (). Ini sangat penting. Ingat bahwa gtk_main () adalah loop tanpa akhir.
Jika pengguna menutup jendela itu, itu menghancurkan widget tetapi
eksekusi masih dalam loop gtk_main () dan program belum benar-benar
dihentikan. Ini akan "muncul" karena jendela hilang, tetapi masih akan berjalan. Dengan menangkap sinyal "hancurkan" kita dapat keluar dari loop itu ketika pengguna menghancurkan (menutup) jendela. Aha, semuanya masuk akal sekarang.
Satu hal lagi yang perlu diperhatikan, adalah sinyal "delete-event"
dapat mengembalikan nilai jika Anda ingin mencegahnya terjadi. "Delete-event" terjadi ketika widget (jendela) meminta dihancurkan.
Kami dapat menghentikan hal ini terjadi jika, misalnya, kami ingin
terlebih dahulu meminta pengguna untuk memastikan mereka ingin berhenti.
Dengan kotak dialog dan kode kondisional, kita dapat mengembalikan 0
jika mereka yakin mereka ingin berhenti, dan 1 jika mereka tidak
benar-benar ingin berhenti.
67: void <br style="font-family: monospace" /> 68: on_toolbutton_new_clicked (GtkWidget * w, GdkEventKey * e) <br style="font-family: monospace" /> 69: {<br style = "font -family: monospace "/> 70: / * bilah alat 'Baru' diklik * / <br style="font-family: monospace" /> 71: g_print (" main.c: on_toolbutton_new_clicked () "); <br style = "font-family: monospace" /> 72:}
SEKIAN DAN TERIMAKASIH:)