Редактирование: 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+]] |