in reply to Re^4: A question on using Tk::ItemStyle in Tk::Tree
in thread A question on using Tk::ItemStyle in Tk::Tree

choroba will likely come along with some more details for you, but maybe this will suffice for now, given:

$mw->after( 'idle', [ configure => $styleref_select_parent, -background => 'cyan' ], );

Even though it could be made more clear, we do see in the Internal Details documentation:

$time is the string 'idle', representing an idle queue timer, or a integer millisecond value.

If you never wanted to use that idle string anomaly, there is an ->afterIdle method. The equivalent of the above could be coded:

$mw->afterIdle([ configure => $styleref_select_parent, -background => +'cyan' ]);

The See Also links to Tk::callbacks where it shows the valid ways to specify a callback, one of which is:

[ 'methodname', args... ], ...

So going back to the sample from Khen1950fx, we see that he passes 'configure', as the method name, and $styleref_select_parent as the object reference that will be passed as the first argument to Tk::ItemStyle::configure, along with the with arguments to change the background color. Incidentally, the fact that after() method is attached to the "$mw" object means that the timer will be cancelled if the MainWindow is destroyed before it fires.

Here's one last example, that shows the square brackets turn out to be optional in this case, as well. After two seconds, set the entire background color:

$mw->after( 2000 => configure => $tree, -background => 'green' );

Replies are listed 'Best First'.
Re^6: A question on using Tk::ItemStyle in Tk::Tree
by Anonymous Monk on Nov 05, 2014 at 08:13 UTC

        I was waiting and hoping if choroba would also respond. Anyway, this kind of detailed response from you does help for newbie like me. I had to repeatedly read through your response and hence it took me sometime to go through the after call details you specified.

    1. Now it appears to me that this afterIdle construct,
      $mw->after( 'idle', [configure => $styleref_select_parent, -background => 'cyan' ], );
      in this particular scenario can be replaced by:

       $styleref_select_parent->configure(-background => 'cyan');
      Is my observation correct ?(after all I got the same output) If not, is there any advantage in going for a Tk::After call?

    2. Refering to your last example: As per the docs,

      (on Tk::Callbacks) the callback when using methodname has the syntax,

           ... => ['methodname', args... ] ...

      and the Tk::after method has the syntax
      after(*ms*, *callback*?).
      So how do these fit in to permit the syntax  2000=> configure => $tree
      in your code:
      $mw->after( 2000 => configure => $tree, -background => 'green' ); ?

    3. I'm eagerly trying to get a handle in understanding this afterIdle method. So I chanced to come across the problem Table matrix suspected selected cell discrepancy and the solution to it Tablematrix 'odd' behaviour of mouse and key solved. where the method
      sub brscmd { my ($previous_index, $actual_index) = @_; my ($row, $col) = split ',', $actual_index; my ($sel, $js); $sel = $t->curselection(); # <-- THE PROBLEM print "@$sel\n"; foreach $js (@$sel) { print "\n[brscmd] actual index <$actual_index> from curselection <$js>\n"; } }
      was replaced by
      sub brscmd { my ($previous_index, $actual_index) = @_; my ($row, $col) = split ',', $actual_index; my ($sel, $js); $t->after( 'idle', # <-- THE SOLUTION sub{ my $sel = $t->curselection(); print "@$sel\n"; foreach $js (@$sel) { print "[brscmd] actual index <$actual_index> from curselection <$js> last_button_key <$last_button_key>\n"; } } ); }
      and things just happen to work fine.

      But I'm unable to grasp the idea behind using  afterIdle call here.

    4. I realize that the number of monks responding to questions on Perl/Tk is generally less than what is comes to other areas of Perl. Since last week the count is again down by 1 after very useful zentara bid adieu to PM.

      So any information monks provide, I say sincerely, will be useful indeed.
      Many Thanks

      Hi there,

      It looks like you did some research and are being quite thoughtful about what's going on in this case. I'm far from a Tk expert, but maybe can point you in the right direction at least.

      As for your first observation, yes you're correct. Your substituted code should be fine in this case. In general you only need to wait for Idle to ensure that a previous operation completes.

      Next, you ask:

                   after(*ms*, *callback*?).
          So how do these fit in to permit the syntax  2000=> configure => $tree in your code:
          $mw->after( 2000 => configure => $tree, -background => 'green' ); ?
      

      The syntax is unfortunate, it's equivalent to this which is more clear:

      $mw->after( 2000, ('configure', ($tree, -background => 'green') ) );

      Which says, after 2 seconds, call the "configure" method of the $tree object, with everything that follows as the remaining arguments. What might be slightly confusing is that $tree is considered an argument to the method. If you look at modules that implement a class, each method takes the object reference as the first argument. That's why in sub's that implement a class method, you'll typically see something like this:

      sub method_name { my $self = shift; ... }

      And from then on the sub will use $self as a handle to the current object being operated on. After the shift, the @_ array has all of the actual arguments which were passed to the method.

      As for your last question, if you read closely the description given in Re^6: Table matrix suspected selected cell discrepancy, you'll see that what is happening, is that when the mouse is clicked, the TableMatrix $t has its "curselection" updated before the brscmd sub gets called (as desired). However, Tk calls brscmd _first_ when the keystroke event fires. The update of the "curselection" will happen after brscmd returns (too late).

      Tk keeps a list of things it must do; multiple callbacks it must make that have been registered to a given event. So in the example above, after brscmd returns, Tk still has on its list of callbacks the TableMatrix, which will update its "curselection" and then return control to Tk, which may make additional callbacks if there are any remaining.

      When all this work gets done and Tk has nothing else to do until the next keyboard or mouse event happen, it enters "idle" mode. And boom, all the callbacks registered to the idle timer are run.

      So, the answer as to why the afterIdle solved the problem in the example you found. It was so that Tk could continue its job, allowing the TableMatrix to update, at which point Tk goes idle, and only then calling the afterIdle code which can reliably depend on the correct value being available via $t->curselection.