10.2. View

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.CellRendererTextPenampil data text. Data dari model akan ditampilkan sebagai text/string, baik data string, integer atau yang lain.
gtk.CellRendererTogglePenampil data toggle. Umumnya menampilkan data dengan nilai boolean, TRUE atau FALSE.
gtk.CellRendererPixbufPenampil 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.

Gambar 10.1. TreeView

TreeView

10.2.1. Selection

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 :

Gambar 10.2. TreeView Selection

TreeView Selection

10.2.2. Atribut

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 :

Gambar 10.3. TreeView Attribute

TreeView Attribute

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_rendererCellRenderer di kolom ini.
celldatafunctionfungsi yang akan mengubah atribut cell_renderer.
func_datadata 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:

Gambar 10.4. TreeView Attribute dengan fungsi

TreeView Attribute dengan fungsi