Tentu kita pernah melihat aplikasi yang menampilkan direktori dan berkas-berkasnya. Kita dapat memilih apakah direktori dan berkas ditampilkan dengan gambar icon yang besar beserta nama berkasnya. Atau ditampilkan secara detail dengan icon yang kecil, nama berkas, ukuran berkas dan tanggal. Kedua tampilan ini menggambarkan data yang sama. Dengan kata lain, sebuah model dapat mempunyai lebih dari satu view dengan tampilan yang berbeda.
Tugas utama dari TreeView, tentu saja, menampilkan isi data dari model. Namun sebelum itu kita lihat dahulu struktur TreeView ini. Di dalam TreeView terdiri dari beberapa kolom. Kolom ini berupa object gtk.TreeViewColumn. Setiap kolom dalam TreeView hanya menampilkan data yang sejenis. Penampil data ini disebut CellRenderer. Ada tiga jenis CellRenderer yang siap pakai :
| gtk.CellRendererText | Penampil data text. Data dari model akan ditampilkan sebagai text/string, baik data string, integer atau yang lain. |
| gtk.CellRendererToggle | Penampil data toggle. Umumnya menampilkan data dengan nilai boolean, TRUE atau FALSE. |
| gtk.CellRendererPixbuf | Penampil pixbuf. Menampilkan gambar dengan format pixbuf. |
Setiap jenis CellRenderer mempunyai atribut yang dapat kita hubungkan dengan nilai data dari model. Misalnya gtk.CellRendererText mempunyai atribut "text" yang dapat kita hubungkan dengan salah satu kolom dari model.
Contoh pertama dari penggunaan gtk.TreeView.
import gtk
import gobject
def delete_event(widget, event, data=None):
return gtk.FALSE
def destroy(widget, data=None):
gtk.main_quit()
def mymain():
# membuat model
model = gtk.TreeStore(gobject.TYPE_STRING,gobject.TYPE_STRING,gobject.TYPE_STRING)
# mengisi model dengan data
iter = model.append(None, None) # iterator baris baru
model.set_value(iter, 0, "Linkin' Park") # isi kolom pertama
model.set_value(iter, 1, "Hybrid Theory") # isi kolom kedua
model.set_value(iter, 2, "Mobil") # isi kolom ketiga
citer = model.append(iter, None) # menambah baris baru sebagai child dari baris di atas
# isi datanya dengan fungsi set(iterator, ....)
# .... adalah pasangan kolom dengan data, mis kolom 1 berisi data "Meteora"
model.set(citer, 0, None, 1, "Meteora", 2, "Rumah")
# membuat tree view
tree_view = gtk.TreeView(model)
tree_view.show()
# membuat renderer kolom 0
renderer = gtk.CellRendererText()
# membuat column view
col_view = gtk.TreeViewColumn("Artis",renderer, text=0)
tree_view.append_column(col_view)
# membuat renderer kolom 1
renderer = gtk.CellRendererText()
# membuat column view
col_view = gtk.TreeViewColumn("Album",renderer, text=1)
tree_view.append_column(col_view)
# membuat renderer kolom 2
renderer = gtk.CellRendererText()
# membuat column view
col_view = gtk.TreeViewColumn("Lokasi",renderer, text=2)
tree_view.append_column(col_view)
# membuat scrolled window
scrolled_window = gtk.ScrolledWindow()
scrolled_window.set_border_width(10)
scrolled_window.add(tree_view)
scrolled_window.show()
#membuat window utama
main_window = gtk.Window()
main_window.set_title("Demo TreeView")
main_window.connect("delete_event", delete_event)
main_window.connect("destroy", destroy)
main_window.add(scrolled_window)
main_window.set_default_size(300,150)
main_window.show()
gtk.main()
if __name__ == "__main__":
mymain()
Tampilan yang tampak akan seperti gambar berikut.
gtk.Selection adalah object yang membantu dalam penanganan pemilihan (selection) baris. Object ini didapat dari method get_selection dari object model. Dengan object ini kita dapat mengatur bagaimana efek pemilihan pada Treeview.
Kita dapat menambahkan kode berikut setelah object tree_view dibuat pada contoh diatas dibuat.
# selection object
selection = tree_view.get_selection()
selection.set_mode(gtk.SELECTION_MULTIPLE)
selection.connect("changed",selection_changed)
Pertama kita mengambil object gtk.Selection. Kemudian kita memastikan moda pemilihan menjadi moda pemilihan ganda. Jika dalam moda pemilihan tunggal, kita hanya dapat memilih satu baris dari TreeView. Sedangkan dalam mode pemilihan ganda, gtk.SELECTION_MULTIPLE, maka kita dapat memilih lebih dari satu baris.
Kemudian kita menghubungkan signal "changed" ke fungsi selection_changed. Dengan definisi fungsi selection_changed seperti berikut :
def selection_changed(selection,*at):
print "selection_changed"
selection.selected_foreach(foreach_selection)
Fungsi ini akan dijalankan setiap kali pemilihan "berubah". Namun penulis perlu memberi catatan bahwa perilaku signal ini agak kurang dapat dipahami. Jadi sebaiknya Anda, menyiapkan kode untuk mengantisipasi pemanggilan callback lebih dari satu kali jika kita melakukan pemilihan (clicking) pada baris yang sama berkali-kali [konfirmasi?].
Karena kita dapat memilih lebih dari satu pilihan, untuk setiap baris yang terpilih kita perlu iterasi. Fungsi foreach_selection akan dijalankan untuk setiap baris yang terpilih.
Contoh definisi fungsi foreach_selection adalah :
def foreach_selection(model, path, iter):
if len(path) > 1:
ppath = path[-1]
piter = model.get_iter(ppath)
print "Artis : %s" % model.get_value(piter, 0)
else:
print "Artis : %s" % model.get_value(iter, 0)
print "Album : %s" % model.get_value(iter, 1)
print "Lokasi : %s" % model.get_value(iter, 2)
Perhatikan penggunaan object treeiter dalam fungsi ini.
Jalankan program yang telah kita tambahkan fungsi-fungsi selection ini melalui konsol terminal (prompt). Buka kedua baris dan pilihlah kedua baris tersebut. Maka akan terlihat keluaran pada konsol seperti berikut :
Sangat dianjurkan untuk melihat dokumentasi referensi dari gtk.CellRenderer dan turunannya. Terutama untuk memperhatikan properti atau atributnya. Salah satu yang telah kita gunakan adalah atribut 'text' dari gtk.CellRendererText yang kita kaitkan dengan salah satu kolom di dalam model. Kita akan coba mengaitkan atribut lainnya.
Sebagai contoh atribut 'background'. Atribut ini akan mempengaruhi warna 'background' dari cell. Warna akan didefiniskan dalam salah satu kolom di dalam model sebagai string.
Dalam contoh program, kita akan menambah satu kolom baru untuk warna.
# membuat model
model = gtk.TreeStore(gobject.TYPE_STRING,gobject.TYPE_STRING,
gobject.TYPE_STRING,gobject.TYPE_STRING)
Dari tiga kolom, menjadi empat kolom. Kolom ke-empat ini akan kita isi data warna. Dengan definisi warna sebagai string misalnya, "lightblue". Atau dengan format RGB string, "8DFF14".
Untuk baris pertama :
model.set_value(iter, 3, "lightblue") # isi kolom keempat
Dan untuk baris ke dua (anak baris pertama) :
model.set(citer, 0, None, 1, "Meteora", 2, "Rumah",3,"#8DFF14")
Selanjutkan kita kaitkan kolom ini dengan cell yang kita kehendaki. Misalnya untuk 'background' cell kolom kedua.
col_view = gtk.TreeViewColumn("Album",renderer, text=1, background=3)
Perhatikan kita menambahkan pasangan atribut=kolom, 'background=3' , pada kode di atas.
Setelah kita tambahkan kode-kode di atas dalam contoh program sebelumnya menjadi progam baru maka aplikasinya akan tampak seperti :
Tentu saja kita dapat mengaitkan atribut lain ke kolom model yang lain. Selain dari pola pemetaan seperti ini terdapat cara lain yang lebih fleksibel. Kita dapat membuat suatu fungsi yang akan mengubah atribut CellRenderer sesuai dengan data dalam model.
gtk.TreeViewColumn mempunyai method set_cell_data_func.
treeviewcol.set_cell_data_func(cell_renderer,celldatafunction,func_data=None)
| cell_renderer | CellRenderer di kolom ini. |
| celldatafunction | fungsi yang akan mengubah atribut cell_renderer. |
| func_data | data yang disertakan dalam fungsi celldatafunction, jika ada. |
Fungsi celldatafunction argumen mempunyai argumen seperti berikut :
def celldatafunction(column, cell, model, iter, func_data)
Jika dalam bentuk method :
def celldatamethod(self, column, cell, model, iter, func_data)
Kita ubah contoh di atas menjadi 5 kolom. Dengan tambahan untuk kolom status peminjaman dan kolom tanggal seharusnya kembali. Pada saat membuat kolom ke-5 ini kita buat supaya atribut "background"-nya berubah warna. Hijau jika tidak sedang dipinjam. Kuning jika dipinjam namun belum sampai batas waktu pengembalian. Merah jika masih dipinjam setelah lewat batas waktu. Perhatikan pada saat membuat kolom :
# membuat renderer kolom tanggal kembali
renderer = gtk.CellRendererText()
# membuat column view
col_view = gtk.TreeViewColumn("Kembali",renderer)
# mengaitkan fungsi 'kembali_col_func' dengan renderer
col_view.set_cell_data_func(renderer, kembali_col_func)
tree_view.append_column(col_view)
Sedangkan definisi fungsi 'kembali_col_func' seperti berikut :
def kembali_col_func(column, cell, model, iter):
if model.get_value(iter,3): # jika kolom status peminjaman bernilai TRUE
cell.set_property("text", model.get_value(iter,4))
my_time = time.strptime(model.get_value(iter,4),"%Y/%m/%d")
cell.set_property("background", "yellow")
if my_time < time.localtime():
cell.set_property("background", "red") # jika telah lewat batas tanggal
else: # jika kolom status peminjaman bernilai FALSE
cell.set_property("text","")
cell.set_property("background", "green")
Setelah kita tambahkan code diatas dari program treeview2.py menjadi program baru dengan tampilan seperti berikut: