Home  Contents

Advanced widgets in PyGTK

فى هذه الجزئية سنناقش بعض الويدجات المتقدمة

IconView

يستخدم الويدجت IconView لعرض مجموعة من الأيكونات فى صورة شبكة

iconview.py
 
#!/usr/bin/python

# ZetCode PyGTK tutorial 
#
# This example demonstrates the IconView widget.
# It shows the contents of the currently selected
# directory on the disk.
#
# author: jan bodnar
# website: zetcode.com 
# last edited: February 2009

import gtk
import os

COL_PATH = 0
COL_PIXBUF = 1
COL_IS_DIRECTORY = 2


class PyApp(gtk.Window): 
    def __init__(self):
        super(PyApp, self).__init__()
        
        self.set_size_request(650, 400)
        self.set_position(gtk.WIN_POS_CENTER)
        
        self.connect("destroy", gtk.main_quit)
        self.set_title("IconView")
        
        self.current_directory = '/'

        vbox = gtk.VBox(False, 0);
       
        toolbar = gtk.Toolbar()
        vbox.pack_start(toolbar, False, False, 0)

        self.upButton = gtk.ToolButton(gtk.STOCK_GO_UP);
        self.upButton.set_is_important(True)
        self.upButton.set_sensitive(False)
        toolbar.insert(self.upButton, -1)

        homeButton = gtk.ToolButton(gtk.STOCK_HOME)
        homeButton.set_is_important(True)
        toolbar.insert(homeButton, -1)

        self.fileIcon = self.get_icon(gtk.STOCK_FILE)
        self.dirIcon = self.get_icon(gtk.STOCK_OPEN)

        sw = gtk.ScrolledWindow()
        sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
        sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        vbox.pack_start(sw, True, True, 0)

        self.store = self.create_store()
        self.fill_store()

        iconView = gtk.IconView(self.store)
        iconView.set_selection_mode(gtk.SELECTION_MULTIPLE)

        self.upButton.connect("clicked", self.on_up_clicked)
        homeButton.connect("clicked", self.on_home_clicked)

        iconView.set_text_column(COL_PATH)
        iconView.set_pixbuf_column(COL_PIXBUF)

        iconView.connect("item-activated", self.on_item_activated)
        sw.add(iconView)
        iconView.grab_focus()

        self.add(vbox)
        self.show_all()

    def get_icon(self, name):
        theme = gtk.icon_theme_get_default()
        return theme.load_icon(name, 48, 0)
    

    def create_store(self):
        store = gtk.ListStore(str, gtk.gdk.Pixbuf, bool)
        store.set_sort_column_id(COL_PATH, gtk.SORT_ASCENDING)
        return store
            
    
    def fill_store(self):
        self.store.clear()

        if self.current_directory == None:
            return

        for fl in os.listdir(self.current_directory):
        
            if not fl[0] == '.': 
                if os.path.isdir(os.path.join(self.current_directory, fl)):
                    self.store.append([fl, self.dirIcon, True])
                else:
                    self.store.append([fl, self.fileIcon, False])             
        
    

    def on_home_clicked(self, widget):
        self.current_directory = os.path.realpath(os.path.expanduser('~'))
        self.fill_store()
        self.upButton.set_sensitive(True)
        
    
    def on_item_activated(self, widget, item):

        model = widget.get_model()
        path = model[item][COL_PATH]
        isDir = model[item][COL_IS_DIRECTORY]

        if not isDir:
            return
            
        self.current_directory = self.current_directory + os.path.sep + path
        self.fill_store()
        self.upButton.set_sensitive(True)
    

    def on_up_clicked(self, widget):
        self.current_directory = os.path.dirname(self.current_directory)
        self.fill_store()
        sensitive = True
        if self.current_directory == "/": sensitive = False
        self.upButton.set_sensitive(sensitive)
    

PyApp()
gtk.main()

فى هذا المثال، نعرض الأيكونات للمجلد المختار الحالى، ولديه شريط ادوات وزرين up و home ونستخدمهم لتصفح النظام

 self.current_directory = '/'

current_directory هو المجلد اللذى سيتم عرض محتواه فى ال IconView

 def create_store(self):
     store = gtk.ListStore(str, gtk.gdk.Pixbuf, bool)
     store.set_sort_column_id(COL_PATH, gtk.SORT_ASCENDING)
     return store

ال ListStore هو مخزن لعنصر (ويمثل بياناته بأعمدة) وهنا نستخدمه لتخزين بيانات ال IconView فتقوم الطريقة create_store بإنشاء المخزن بثلاث معاملات (اسم المجلدو كائن pixbuf و قيمة منطقية لتحدد ماذا كان مجلد او ملف-



 if not fl[0] == '.': 
     if os.path.isdir(os.path.join(self.current_directory, fl)):
         self.store.append([fl, self.dirIcon, True])
     else:
         self.store.append([fl, self.fileIcon, False])     

فى الطريقة fill_store .. ننشئ مخزن البيانات مكون من المجلدات عدا المخفية -تبدأ ب " . “

 def on_home_clicked(self, widget):
     self.current_directory = os.path.realpath(os.path.expanduser('~'))
     self.fill_store()
     self.upButton.set_sensitive(True)



اذا ضغطنا على الزر Home، نحصل على مسار المنزل ونعيد ملء مخزن البيانات وننشط الزر up

فى الطريقة on_item_activated نتفاعل مع حدث -يحدث عند الضغط على عنصر من عناصر ال icon view -



 model = widget.get_model()
 path = model[item][COL_PATH]
 isDir = model[item][COL_IS_DIRECTORY]

 if not isDir:
     return

نحصل على مسار العنصر المنشط، ثم نقرر ماإذا كان مجلد او ملف -نقوم بالخروج فورا-

 self.current_directory = self.current_directory + os.path.sep + path
 self.fill_store()
 self.upButton.set_sensitive(True)

فى حال انه مجلد، نستبدل الجذر بالمسار الحالى ونعيد ملء مخزن البيانات وننشط حساسية الزر up

 def on_up_clicked(self, widget):
     self.current_directory = os.path.dirname(self.current_directory)
     self.fill_store()
     sensitive = True
     if self.current_directory == "/": sensitive = False
     self.upButton.set_sensitive(sensitive)

عند الضغط على الزر up ، نستبدل مجلد الجذر بأبيه ونعيد ملء المخزن، لاحظ انه سيكون منشط فقط عند وجودنا فى اى مجلد اقل من /


IconView

Figure: IconView



ListView

فى المثال التالى، نعرض ويدجت الشجرة ليمثل list view، مرة اخرى سنستخدم ال ListStore ليمثل البيانات

listview.py
 
#!/usr/bin/python

# ZetCode PyGTK tutorial 
#
# This example shows a TreeView widget
# in a list view mode
#
# author: jan bodnar
# website: zetcode.com 
# last edited: February 2009


import gtk

actresses = [('jessica alba', 'pomona', '1981'), ('sigourney weaver', 'new york', '1949'),
    ('angelina jolie', 'los angeles', '1975'), ('natalie portman', 'jerusalem', '1981'),
    ('rachel weiss', 'london', '1971'), ('scarlett johansson', 'new york', '1984' )]


class PyApp(gtk.Window): 
    def __init__(self):
        super(PyApp, self).__init__()
        
        self.set_size_request(350, 250)
        self.set_position(gtk.WIN_POS_CENTER)
        
        self.connect("destroy", gtk.main_quit)
        self.set_title("ListView")

        vbox = gtk.VBox(False, 8)
        
        sw = gtk.ScrolledWindow()
        sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
        sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        
        vbox.pack_start(sw, True, True, 0)

        store = self.create_model()

        treeView = gtk.TreeView(store)
        treeView.connect("row-activated", self.on_activated)
        treeView.set_rules_hint(True)
        sw.add(treeView)

        self.create_columns(treeView)
        self.statusbar = gtk.Statusbar()
        
        vbox.pack_start(self.statusbar, False, False, 0)

        self.add(vbox)
        self.show_all()


    def create_model(self):
        store = gtk.ListStore(str, str, str)

        for act in actresses:
            store.append([act[0], act[1], act[2]])

        return store


    def create_columns(self, treeView):
    
        rendererText = gtk.CellRendererText()
        column = gtk.TreeViewColumn("Name", rendererText, text=0)
        column.set_sort_column_id(0)    
        treeView.append_column(column)
        
        rendererText = gtk.CellRendererText()
        column = gtk.TreeViewColumn("Place", rendererText, text=1)
        column.set_sort_column_id(1)
        treeView.append_column(column)

        rendererText = gtk.CellRendererText()
        column = gtk.TreeViewColumn("Year", rendererText, text=2)
        column.set_sort_column_id(2)
        treeView.append_column(column)


    def on_activated(self, widget, row, col):
        
        model = widget.get_model()
        text = model[row][0] + ", " + model[row][1] + ", " + model[row][2]
        self.statusbar.push(0, text)



PyApp()
gtk.main()

فى مثالنا، سنعرض قائمة من 6 ممثلات "تمثل فى 6 صفوف" فى ويدجت الشجرة، كل صف يشمل اسم ومحل الميلاد وتاريخه

 def create_model(self):
     store = gtk.ListStore(str, str, str)

     for act in actresses:
         store.append([act[0], act[1], act[2]])

     return store

ننشئ المودل (البيانات اللتى سيتم تمثيلها)، هنا ننشئ List Store، ولها 3 معاملات، اسم الممثلة، تاريخ ميلادها، ومحل الميلاد

 treeView = gtk.TreeView(store)
 treeView.connect("row-activated", self.on_activated)
 treeView.set_rules_hint(True)

هنا ننشئ ويدجت الشجرة، لاحظ انه يأخذ (ListStore) ليحدد البيانات اللتى سيعرضها. الطريقة set_rules_hint تغير لون الخلفية بين كل صفين -كما بالصورة-



 rendererText = gtk.CellRendererText()

 column = gtk.TreeViewColumn("Name", rendererText, text=0)
 column.set_sort_column_id(0)    
 treeView.append_column(column)

فى الطريقة create_columns ، نضيف 3 اعمدة لعارض الشجرة. الكود بالأعلى ينشئ عمود لعرض اسماء الممثلات. ال CellRendererText يحصل على التكست من العمود الأول من المودل -0-



 def on_activated(self, widget, row, col):
        
     model = widget.get_model()
     text = model[row][0] + ", " + model[row][1] + ", " + model[row][2]
     self.statusbar.push(0, text)

عند الضغط على العنصر، نعرض الصف كله على شريط الحالة


ListView

Figure: ListView



Tree

فى هذه الجزئية سنتعرض لويدجت الشجرة TreeView ليمثل هيكلية البيانات

tree.py

#!/usr/bin/python

# ZetCode PyGTK tutorial 
#
# This example shows a TreeView widget
# in a tree view mode
#
# author: jan bodnar
# website: zetcode.com 
# last edited: February 2009

import gtk


class PyApp(gtk.Window): 
    def __init__(self):
        super(PyApp, self).__init__()
        
        self.set_size_request(400, 300)
        self.set_position(gtk.WIN_POS_CENTER)
        
        self.connect("destroy", gtk.main_quit)
        self.set_title("Tree")

        tree = gtk.TreeView()
        
        languages = gtk.TreeViewColumn()
        languages.set_title("Programming languages")
 
        cell = gtk.CellRendererText()
        languages.pack_start(cell, True)
        languages.add_attribute(cell, "text", 0)
 
        treestore = gtk.TreeStore(str)
 
        it = treestore.append(None, ["Scripting languages"])
        treestore.append(it, ["Python"])
        treestore.append(it, ["PHP"])
        treestore.append(it, ["Perl"])
        treestore.append(it, ["Ruby"])
 
        it = treestore.append(None, ["Compiling languages"])
        treestore.append(it, ["C#"])
        treestore.append(it, ["C++"])
        treestore.append(it, ["C"])
        treestore.append(it, ["Java"])
 
        tree.append_column(languages)
        tree.set_model(treestore)

        self.add(tree)
        self.show_all()


PyApp()
gtk.main()

فى هذه المرة سنستخدم ويدجت ال TreeView لعرض بيانات هيكلية

 tree = gtk.TreeView()

انشاء ويدجت الشجرة TreeView

 languages = gtk.TreeViewColumn()
 languages.set_title("Programming languages")

لديها عمود واحد عنوانه Programming Languages

 cell = gtk.CellRendererText()
 languages.pack_start(cell, True)
 languages.add_attribute(cell, "text", 0)

نعرض بعض البيانات النصية

 treestore = gtk.TreeStore(str)

نخزن البيانات وهنا نستخدم نوع جديد من المخازن وهو ال TreeStore

 it = treestore.append(None, ["Scripting languages"])
 treestore.append(it, ["Python"])
 treestore.append(it, ["PHP"])

نضيف البيانات للشجرة، الكائن TreeIter يستخدم للوصول للبيانات فى كل صف



 tree.append_column(languages)

اضافة العمود

 tree.set_model(treestore)

اضافة المودل


Tree

Figure: Tree



فى هذا الفصل تحدثنا عن ويدجات متقدمة



Home ‡ Contents ‡ Top of Page