ruby-****@sourc*****
ruby-****@sourc*****
2009年 10月 5日 (月) 21:54:41 JST
------------------------- REMOTE_ADDR = 80.99.10.211 REMOTE_HOST = URL = http://ruby-gnome2.sourceforge.jp/hiki.cgi?tut-gtk2-treev-pxbr ------------------------- @@ -9,7 +9,7 @@ {{image_left("treev-crs-01.png")}} -As you can see there are no pixbuf objects on this image on the left. This is because of a problem in GTK+. Namely, currently (as of Ruby 1.8.6 and Ruby-GNOME2 rel.: 2-0.17.0-rc1) {{image_right("dialog-warning.png")}}two important methods: Gtk::CellRendererPixbuf#set_attributes and Gtk::CellRendererPixbuf#set_attributes, do not work as expected. It looks that this is a combined C GTK+ as well as Ruby GTK+ problem. I have compiled the C example from Andrew Klause's book, and it exhibits exactly the same problems as my Ruby translation. You may check it out by clicking on ((<pixbuf-rdr.c|tut-gtk2-treev-treev-pxbr-cgtk-01>)) +Please update screenshot, since we have nice icons now. {{br}} @@ -18,59 +18,58 @@ #!/usr/bin/env ruby require 'gtk2' - + # Add three columns to the GtkTreeView. All three of the # columns will be displayed as text, although one is a boolean # value and another is an integer. def setup_tree_view(treeview) - - renderer = Gtk::CellRendererToggle.new - column = Gtk::TreeViewColumn.new("Buy", renderer, "active" => $buy_index) - - renderer.activatable = true - renderer.signal_connect('toggled') do |w, path| - iter = treeview.model.get_iter(path) - iter[$buy_index] = !iter[$buy_index] if (iter) - end - treeview.append_column(column) - - renderer = Gtk::CellRendererText.new - column = Gtk::TreeViewColumn.new("Count", renderer, "text" => $qty_index) - treeview.append_column(column) - - column = Gtk::TreeViewColumn.new - column.title = "Product" - - # Create a a tree view column with two renderers, one a pixbuf - # and one text. - renderer = Gtk::CellRendererPixbuf.new - column.pack_start(renderer, false) - - # column.set_attributes(renderer, "pixbuf" => Gtk::Stock::DIALOG_QUESTION) - # column.add_attribute(renderer, "pixbuf", Gtk::Stock::DIALOG_QUESTION) - - renderer = Gtk::CellRendererText.new - column.pack_start(renderer, true) - column.add_attribute(renderer, "text", $prod_index) - treeview.append_column(column) + + renderer = Gtk::CellRendererToggle.new + column = Gtk::TreeViewColumn.new("Buy", renderer, "active" => $buy_index) + + renderer.activatable = true + renderer.signal_connect('toggled') do |w, path| + iter = treeview.model.get_iter(path) + iter[$buy_index] = !iter[$buy_index] if (iter) + end + treeview.append_column(column) + + renderer = Gtk::CellRendererText.new + column = Gtk::TreeViewColumn.new("Count", renderer, "text" => $qty_index) + treeview.append_column(column) + + column = Gtk::TreeViewColumn.new + column.title = "Product" + + # Create a a tree view column with two renderers, one a pixbuf + # and one text. + renderer = Gtk::CellRendererPixbuf.new + column.pack_start(renderer, false) + column.add_attribute(renderer, 'stock_id', $pixbuf) + + renderer = Gtk::CellRendererText.new + column.pack_start(renderer, true) + column.add_attribute(renderer, "text", $prod_index) + treeview.append_column(column) end - + window = Gtk::Window.new(Gtk::Window::TOPLEVEL) window.resizable = true window.title = "Grocery List" window.border_width = 10 window.signal_connect('delete_event') { Gtk.main_quit } window.set_size_request(275, 200) - + + class GroceryItem - attr_accessor :product_type, :buy, :quantity, :product - def initialize(t,b,q,p) - @product_type, @buy, @quantity, @product = t, b, q, p - end + attr_accessor :product_type, :buy, :quantity, :product + def initialize(t,b,q,p) + @product_type, @buy, @quantity, @product = t, b, q, p + end end - $buy_index = 0; $qty_index = 1; $prod_index = 2 + $buy_index = 0; $qty_index = 1; $prod_index = 2; $pixbuf = 3 $p_category = 0; $p_child = 1 - + list = Array.new list[0] = GroceryItem.new($p_category, true, 0, "Cleaning Supplies") list[1] = GroceryItem.new($p_child, true, 1, "Paper Towels") @@ -81,86 +80,60 @@ list[6] = GroceryItem.new($p_child, true, 1, "Milk") list[7] = GroceryItem.new($p_child, false, 3, "Chips") list[8] = GroceryItem.new($p_child, true, 4, "Soda") - + treeview = Gtk::TreeView.new setup_tree_view(treeview) - + # Create a new tree model with three columns, as Boolean, # integer and string. - store = Gtk::TreeStore.new(TrueClass, Integer, String) - + store = Gtk::TreeStore.new(TrueClass, Integer, String, String) + # Avoid creation of iterators on every iterration, since they # need to provide state information for all iterations. Hence: # establish closure variables for iterators parent and child. parent = child = nil - + # Add all of the products to the GtkListStore. list.each_with_index do |e, i| - - # If the product type is a category, count the quantity - # of all of the products in the category that are going - # to be bought. - if (e.product_type == $p_category) - j = i + 1 - - # Calculate how many products will be bought in - # the category. - while j < list.size && list[j].product_type != $p_category - list[i].quantity += list[j].quantity if list[j].buy - j += 1 - end - - # Add the category as a new root (parent) row (element). - parent = store.append(nil) - # store.set_value(parent, $buy_index, list[i].buy) # <= same as below - parent[$buy_index] = list[i].buy - parent[$qty_index] = list[i].quantity - parent[$prod_index] = list[i].product - - # Otherwise, add the product as a child row of the category. - else - child = store.append(parent) - # store.set_value(child, $buy_index, list[i].buy) # <= same as below - child[$buy_index] = list[i].buy - child[$qty_index] = list[i].quantity - child[$prod_index] = list[i].product - end + + # If the product type is a category, count the quantity + # of all of the products in the category that are going + # to be bought. + if (e.product_type == $p_category) + j = i + 1 + + # Calculate how many products will be bought in + # the category. + while j < list.size && list[j].product_type != $p_category + list[i].quantity += list[j].quantity if list[j].buy + j += 1 + end + + # Add the category as a new root (parent) row (element). + parent = store.append(nil) + # store.set_value(parent, $buy_index, list[i].buy) # <= same as below + parent[$buy_index] = list[i].buy + parent[$qty_index] = list[i].quantity + parent[$prod_index] = list[i].product + parent[$pixbuf] = Gtk::Stock::DIALOG_INFO + + # Otherwise, add the product as a child row of the category. + else + child = store.append(parent) + # store.set_value(child, $buy_index, list[i].buy) # <= same as below + child[$buy_index] = list[i].buy + child[$qty_index] = list[i].quantity + child[$prod_index] = list[i].product + child[$pixbuf] = Gtk::Stock::ABOUT + end end - + # Add the tree model to the tree view treeview.model = store treeview.expand_all - + scrolled_win = Gtk::ScrolledWindow.new scrolled_win.add(treeview) scrolled_win.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC) window.add(scrolled_win) window.show_all Gtk.main - -For your convenience I have included the API documentation for the two offending methods: - - #--- Gtk::TreeViewColumn#add_attribute(cell_renderer, attribute, column) - # - # Adds an attribute mapping to the list in the Gtk::TreeViewColumn. - # The column is the column of the model to get a value from, and - # the attribute is the parameter on cell_renderer to be set from - # the value. So for example if column 2 of the model contains - # strings, you could have the :text attribute of a - # Gtk::CellRendererText get its values from column 2. - # - # * cell_renderer: the Gtk::CellRenderer to set attributes on - # * attribute: An attribute on the renderer(Symbol or String) - # * column: The column position on the model to get the attribute from. - # * Returns: self - # - #--- Gtk::TreeViewColumn#set_attributes(cell_renderer, attributes) - # - # Sets the attributes in the list as the attributes of the - # Gtk::TreeViewColumn. All existing attributes are removed, and - # replaced with the new attributes. - # You should set cell_renderer to the Gtk::TreeViewColumn before - # call this method. - # - # * cell_renderer: The Gtk::CellRenderer we're setting the attributes of - # * attributes: a hash of attributes. See Gtk::TreeViewColumn.new