ruby-****@sourc*****
ruby-****@sourc*****
2012年 8月 25日 (土) 01:41:02 JST
------------------------- REMOTE_ADDR = 70.49.49.99 REMOTE_HOST = URL = http://ruby-gnome2.sourceforge.jp/hiki.cgi?tut-gtk2-treev-rr ------------------------- @@ -103,10 +103,9 @@ {{br}} - === Tree Row References -Beside an important role of watching a tree model for changes Gtk::TreeRowReference objects are extremely helpful in providing stable reference points to the information related to the constantly varying pointers to the rows in the tree model. To understand this, one has to be familiar with the tree model, hence we will defer this explanation until we gather a bit more experience with this topics. For those of you, who would like to jump ahead following is the link that talks about references as a reliable means to track the position of rows within the tree: (((<Removing Multiple Rows|tut-gtk2-treev-addrnhs#Removing Multiple Rows>))). However, as the agents that monitor for changes in the tree model, we need to know, that internally they connect to the ((*row-inserted,*)) ((*row-deleted,*)) and ((*row-reordered*)) signals, updating the stored path based on the changes. +Gtk::TreeRowReference objects are used to watch a tree model for changes. Internally they connect to the((*row-inserted, row-deleted,*))and((*row-reordered*)) signals, updating the stored path based on the changes. New tree row references are created with Gtk::TreeRowReference.new: @@ -120,3 +119,23 @@ If you need to retrieve a path, you can use Gtk::TreeRowReference#path instance method, which will return nil if if the row no longer exists within the model. As you can see from the API document segment above, the tree references are able to update the tree path based on changes within the tree model, but if you remove all the elements from the same level as the tree path's row, it will no longer have a row to point to. You should be aware that tree row references do add a bit of a processing overhead, when adding, removing, or sorting rows within a tree model, since the references will have to handle all signals emitted by these actions. + + + +=== TreeRowReference to the rescue: + +While traversing a store with a Gtk::TreeModel#each loop it can be danderous add or remove rows from the store. It is easy to to remove rows with either Gtk::ListStore#remove or Gtk::TreeStore#remove. The removed row will also be removed from the tree view as well. + +As stated, removing rows in a loop can be a problem, however. Following is an example showing, how to avoid such a problem, namely, it is not possible to traverse a store with Gtk::TreeModel#each, check whether the given row should be removed and then simply remove it by calling one of the models' remove methods. This can not work, because when the model is changed from within the foreach loop, this invalidates tree iters in the each method, and causes unpredictable behaviour. + +In events like this Gtk::TreeRowReference will help us: + + underage = [] + liststore.each do |model,path,iter| + (iter[0] == false) and underage.push(Gtk::TreeRowReference.new(model,path)) + end + + underage.each do |rowref| + (path = rowref.path) and liststore.remove(liststore.get_iter(path)) + end + +Gtk::ListStore#clear and Gtk::TreeStore#clear come in handy if you want to remove all rows.