ruby-****@sourc*****
ruby-****@sourc*****
2012年 10月 7日 (日) 06:59:02 JST
------------------------- REMOTE_ADDR = 184.145.80.187 REMOTE_HOST = URL = http://ruby-gnome2.sourceforge.jp/hiki.cgi?tut-gtk2-treev-spbttr ------------------------- @@ -6,7 +6,8 @@ In session about "Numeric/Text Data Entry" we have learnt about the Gtk::SpinButton. While Gtk::CellRendererText can display numbers, a better option is to use Gtk::CellRendererSpin. Instead of displaying a Gtk::Entry when the content is to be edited, a Gtk::CellRendererSpin is used. -{{image_left("treev-crs-01.png")}} +{{image_left("treev-crs-03-spin-btts.png")}} + Just like with the pixbuf renderer example there is a problem with the spin button renderers, you can see this from the image on the the left, where we would expect spin buttons in the Count column. Obviously there is again a problem in GTK+. As of Ruby 1.8.6 and Ruby-GNOME2 rel.: 2-0.17.0-rc1, {{image_right("dialog-warning.png")}} most of the methods in Gtk::CellRendererSpin class do not work as expected. It also 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 ((<treestore-spin.c|tut-gtk2-treev-treev-spin-cgtk-01>)) With Gtk2 2.24.10-3 and Ruby 1.9.3 the example below works if the CellRendererSpin renderer is set to editable @@ -20,44 +21,54 @@ #!/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. + # Add three columns to the tree view. The first of the three + # columns will be displayed as the toggle button, the second + # column will be an editable spin button and the last column + # will be the name of the product category or the product to buy. def setup_tree_view(treeview) renderer = Gtk::CellRendererToggle.new - column = Gtk::TreeViewColumn.new("Buy", renderer, "active" => $buy_index) - + column = Gtk::TreeViewColumn.new("Buy", renderer, "active" => BUY_COLUMN) + renderer.activatable = true renderer.signal_connect('toggled') do |w, path| iter = treeview.model.get_iter(path) - iter[$buy_index] = !iter[$buy_index] if (iter) + iter[BUY_COLUMN] = !iter[BUY_COLUMN] if (iter) end treeview.append_column(column) # Create spin button cell renderer # value, min, max, step, pg-incr, pg-size - adj = Gtk::Adjustment.new(0.0, 0.0, 100.0, 1.0, 2.0, 2.0) + adj = Gtk::Adjustment.new(0.0, 0.0, 100.0, 1.0, 2.0, 0) renderer = Gtk::CellRendererSpin.new renderer.adjustment = adj renderer.signal_connect('edited') do |w, path, new_text| iter = treeview.model.get_iter(path) - iter[$qty_index] = new_text + iter[COUNT_COLUMN] = new_text.to_i end - column = Gtk::TreeViewColumn.new("Count", renderer, "text" => $qty_index) + + # renderer.editable = true + column = Gtk::TreeViewColumn.new("Count-spin", renderer, "text" => COUNT_COLUMN) + column.set_cell_data_func(renderer) do |tvc, cell, model, iter| + cell.editable = iter.has_child? ? false : true + fix_parents_total(iter) if !iter.has_child? + end treeview.append_column(column) renderer = Gtk::CellRendererText.new - column = Gtk::TreeViewColumn.new("Product", renderer, "text" => $prod_index) + column = Gtk::TreeViewColumn.new("Product", renderer, "text" => PRODUCT_COLUMN) 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) + def fix_parents_total(iter) + parent = iter.parent + tmp_iter = parent.first_child + total = 0 + total = tmp_iter[COUNT_COLUMN] if tmp_iter[BUY_COLUMN] + (total += tmp_iter[COUNT_COLUMN] if tmp_iter[BUY_COLUMN]) while tmp_iter.next! + parent[COUNT_COLUMN] = total + end class GroceryItem attr_accessor :product_type, :buy, :quantity, :product @@ -65,19 +75,29 @@ @product_type, @buy, @quantity, @product = t, b, q, p end end - $buy_index = 0; $qty_index = 1; $prod_index = 2 - $p_category = 0; $p_child = 1 + BUY_COLUMN = 0; COUNT_COLUMN = 1; PRODUCT_COLUMN = 2 + P_CATG = 0; P_CHLD = 1 list = Array.new - list[0] = GroceryItem.new($p_category, true, 0, "Cleaning Supplies") - list[1] = GroceryItem.new($p_child, true, 1, "Paper Towels") - list[2] = GroceryItem.new($p_child, true, 3, "Toilet Paper") - list[3] = GroceryItem.new($p_category, true, 0, "Food") - list[4] = GroceryItem.new($p_child, true, 2, "Bread") - list[5] = GroceryItem.new($p_child, false, 1, "Butter") - 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") + list[0] = GroceryItem.new(P_CATG, true, 0, "Cleaning Supplies") + list[1] = GroceryItem.new(P_CHLD, true, 1, "Paper Towels") + list[2] = GroceryItem.new(P_CHLD, true, 3, "Toilet Paper") + list[3] = GroceryItem.new(P_CATG, true, 0, "Food") + list[4] = GroceryItem.new(P_CHLD, true, 2, "Bread") + list[5] = GroceryItem.new(P_CHLD, false, 1, "Butter") + list[6] = GroceryItem.new(P_CHLD, true, 1, "Milk") + list[7] = GroceryItem.new(P_CHLD, false, 3, "Chips") + list[8] = GroceryItem.new(P_CHLD, true, 4, "Soda") treeview = Gtk::TreeView.new setup_tree_view(treeview) @@ -97,30 +107,40 @@ # 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) + if (e.product_type == P_CATG) j = i + 1 # Calculate how many products will be bought in # the category. - while j < list.size && list[j].product_type != $p_category + while j < list.size && list[j].product_type != P_CATG 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 + # store.set_value(parent, BUY_COLUMN, list[i].buy) # <= same as below + parent[BUY_COLUMN] = list[i].buy + parent[COUNT_COLUMN] = list[i].quantity + parent[PRODUCT_COLUMN] = 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 + # store.set_value(child, BUY_COLUMN, list[i].buy) # <= same as below + child[BUY_COLUMN] = list[i].buy + child[COUNT_COLUMN] = list[i].quantity + child[PRODUCT_COLUMN] = list[i].product end end @@ -131,6 +141,22 @@ scrolled_win = Gtk::ScrolledWindow.new scrolled_win.add(treeview) scrolled_win.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC) + + window = Gtk::Window.new("Grocery List (w/spin btt.)") + window.resizable = true + window.border_width = 10 + window.signal_connect('destroy') { Gtk.main_quit } + window.set_size_request(275, 200) window.add(scrolled_win) window.show_all Gtk.main