Редактирование: PyGTK FAQ Advanced Widgets

Материал из Wiki.crossplatform.ru

Перейти к: навигация, поиск
Внимание: Вы не представились системе. Ваш IP-адрес будет записан в историю изменений этой страницы.
Правка может быть отменена. Пожалуйста, просмотрите сравнение версий, чтобы убедиться, что это именно те изменения, которые вас интересуют, и нажмите «Записать страницу», чтобы изменения вступили в силу.
Текущая версия Ваш текст
Строка 1: Строка 1:
 +
In this part of the PyGTK programming tutorial, we will introduce some more advanced widgets in PyGTK.
 +
== IconView ==
 +
The <b>IconView</b> is a widget which displays a list of icons in a grid.
 +
<source lang="python">
 +
#!/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()
 +
</source>
 +
 +
This example shows icons of the currently selected directory. It has a toolbar and two buttons. Up button and home button. We use them to navigate through the file system.
 +
 +
<source lang="python">
 +
self.current_directory = '/'
 +
</source>
 +
 +
The <b>current_directory</b> is the directory, that is displayed by the <b>IconView</b> widget.
 +
 +
<source lang="python">
 +
def create_store(self):
 +
    store = gtk.ListStore(str, gtk.gdk.Pixbuf, bool)
 +
    store.set_sort_column_id(COL_PATH, gtk.SORT_ASCENDING)
 +
    return store
 +
</source>
 +
 +
The <b>ListStore</b>. It is a data model used in <b>IconView</b> widget. It takes three parameters. The directory name, the pixbuf image of the icon and a bool variable, indicating, whether we have a directory or a file.
 +
 +
<source lang="python">
 +
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])   
 +
</source>
 +
 +
In the <b>fill_store()</b> method, we fill the list store with data. Here, we find out all directories in the current path. We exclude the invisible directories, which begin with '.'.
 +
 +
<source lang="python">
 +
def on_home_clicked(self, widget):
 +
    self.current_directory = os.path.realpath(os.path.expanduser('~'))
 +
    self.fill_store()
 +
    self.upButton.set_sensitive(True)
 +
</source>
 +
 +
If we click on the home button, the home directory becomes a current directory. We refill the list store. And make the up button active.
 +
 +
In the <b>on_item_activated()</b> method, we react to an event, which is generated, when we click on a icon from the icon view widget.
 +
 +
<source lang="python">
 +
model = widget.get_model()
 +
path = model[item][COL_PATH]
 +
isDir = model[item][COL_IS_DIRECTORY]
 +
 +
if not isDir:
 +
    return
 +
</source>
 +
 +
We get the path of the activated item. And we determine, if it is a directory or a file. If it is a file, we return.
 +
 +
<source lang="python">
 +
self.current_directory = self.current_directory + os.path.sep + path
 +
self.fill_store()
 +
self.upButton.set_sensitive(True)
 +
</source>
 +
 +
In case it is a directory, we replace the root with the current path, refill the store and make the up button sensitive.
 +
 +
<source lang="python">
 +
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)
 +
</source>
 +
 +
If we click on the up button, we replace the current directory with it's parent directory. Refill the list store.  And the up button is activated, if we are below the root (/) directory of the file system.
 +
 +
[[image: pygtk_faq_iconview.png | center]]
 +
 +
== ListView ==
 +
In the following example, we use the <b>TreeView</b> widget to show a list view. Again the <b>ListStore</b> is used to store data.
 +
<source lang="python">
 +
#!/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()
 +
</source>
 +
 +
In our example, we show a list of six actresses in the <b>TreeView</b> widget. Each of the rows shows the name, the place of born and the year of born for each of them.
 +
 +
<source lang="python">
 +
 +
def create_model(self):
 +
    store = gtk.ListStore(str, str, str)
 +
 +
    for act in actresses:
 +
        store.append([act[0], act[1], act[2]])
 +
 +
    return store
 +
</source>
 +
 +
In the <b>create_model()</b> method, we create the list store.  The list store has three parameters. The name of the actress, the place of born and year of born. This is the data model of our <b>TreeView</b> widget.
 +
 +
<source lang="python">
 +
treeView = gtk.TreeView(store)
 +
treeView.connect("row-activated", self.on_activated)
 +
treeView.set_rules_hint(True)
 +
 +
</source>
 +
 +
Here we create the <b>TreeView</b> widget, taking the list store as a parameter. <b>set_rules_hint()</b> method changes the background color of the every second row in the <b>TreeView</b> widget.
 +
 +
<source lang="python">
 +
rendererText = gtk.CellRendererText()
 +
 +
column = gtk.TreeViewColumn("Name", rendererText, text=0)
 +
column.set_sort_column_id(0)   
 +
treeView.append_column(column)
 +
 +
</source>
 +
 +
In the <b>create_columns()</b> method, we add three columns to our <b>TreeView</b> widget. The above code creates a column displaying names of the actresses. The <b>CellRendererText</b> retrieves its text from the first column of the tree model. (text=0)
 +
 +
<source lang="python">
 +
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)
 +
 +
</source>
 +
 +
If we double click on an item, we display the whole row in the statusbar.
 +
 +
[[image: pygtk_faq_listview.png | center]]
 +
 +
== Tree ==
 +
In the last example of this chapter, we use the <b>TreeView</b> widget to show a hierarchical tree of data.
 +
<source lang="python">
 +
#!/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()
 +
</source>
 +
 +
This time we use the <b>TreeView</b> widget to show hierarchical  data.
 +
 +
<source lang="python">
 +
tree = gtk.TreeView()
 +
</source>
 +
 +
<b>TreeView</b> widget is created.
 +
 +
<source lang="python">
 +
languages = gtk.TreeViewColumn()
 +
languages.set_title("Programming languages")
 +
</source>
 +
 +
It has one column named "Programming languages".
 +
 +
<source lang="python">
 +
cell = gtk.CellRendererText()
 +
languages.pack_start(cell, True)
 +
languages.add_attribute(cell, "text", 0)
 +
</source>
 +
 +
We show textual data in the <b>TreeView</b> widget.
 +
 +
<source lang="python">
 +
treestore = gtk.TreeStore(str)
 +
</source>
 +
 +
To store the data, we use the <b>TreeStore</b> object.
 +
 +
<source lang="python">
 +
it = treestore.append(None, ["Scripting languages"])
 +
treestore.append(it, ["Python"])
 +
treestore.append(it, ["PHP"])
 +
</source>
 +
 +
We append data to the tree. The <b>TreeIter</b> object is used for accessing data in a row.
 +
 +
<source lang="python">
 +
tree.append_column(languages)
 +
</source>
 +
 +
A column is appended to the tree.
 +
 +
<source lang="python">
 +
tree.set_model(treestore)
 +
</source>
 +
 +
Finally, we set a data model for the tree widget.
 +
 +
[[image: pygtk_faq_tree.png | center]]
 +
 +
In this chapter of the PyGTK programming tutorial, we were talking about advanced PyGTK widgets.
 +
 +
[[Категория:Python]]
 +
[[Категория:GTK+]]

Пожалуйста, обратите внимание, что все ваши добавления могут быть отредактированы или удалены другими участниками. Если вы не хотите, чтобы кто-либо изменял ваши тексты, не помещайте их сюда.
Вы также подтверждаете, что являетесь автором вносимых дополнений, или скопировали их из источника, допускающего свободное распространение и изменение своего содержимого (см. Wiki.crossplatform.ru:Авторское право). НЕ РАЗМЕЩАЙТЕ БЕЗ РАЗРЕШЕНИЯ ОХРАНЯЕМЫЕ АВТОРСКИМ ПРАВОМ МАТЕРИАЛЫ!