|
|
Строка 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+]]
| |