in reply to Re^2: Annoying threads share problem!
in thread Annoying threads share problem!

I forgot to mention this, but the searchUpdate thread is supposed to update data in question when user types stuff in the entry... So, I wanted to avoid to do a $mw->repeat(xx...) to update when not neccessary, thus somehow make the searchUpdate thread update! and not the Tk one... hope you see the problem I have becasuse I can't make the searchUpdate update/change the Tk widget when it needs too...

Replies are listed 'Best First'.
Re^4: Annoying threads share problem!
by zentara (Cardinal) on Oct 09, 2005 at 14:49 UTC
    It sounds to me like you have to clarify and rethink your design. If you want to update something, when someone types something into the entrybox. Here is some code which does what your first example attempts to do.

    P.S. Use code blocks around your code examples.

    #!/usr/bin/perl use warnings; use strict; use Tk; use Tk::MatchEntry; use threads; use threads::shared; my %shash; my %hash; my @choices; share $shash{'go'}; share $shash{'die'}; share @choices; $shash{'go'} = 0; $shash{'die'} = 0; @choices = ( "01234", "345345", "64364" ); $hash{'thread'} = threads->new(\&work); my $mw = MainWindow->new( -title => "MatchEntry Test" ); #print Dumper(@choices); my $full_PathMatchEntry = $mw->MatchEntry( -width => 10, -choices => \@choices, -autopopup => 0, -complete => 1, -ignorecase => 1, -maxheight => 15, -background => "#FFFFFF" )->pack( -fill => 'x', -expand => 1, -side => 'left' ); $full_PathMatchEntry->focus; $full_PathMatchEntry->bind( '<KeyPress>', [ sub { shift; my $w = shift; $w->show_listbox(); }, $full_PathMatchEntry ] ); $mw->Button(-text=>'Do_Thread', -command=> sub { $shash{'go'} = 1; $mw->after(1000); $full_PathMatchEntry->configure(-choices => \@choice +s); })->pack(); MainLoop; sub work{ $|++; while(1){ if($shash{'die'} == 1){ goto END }; if ( $shash{'go'} == 1 ){ push( @choices, "/dfgsdfgsdfgsfse/ertuy/" ); $shash{'go'} = 0; #turn off self before returning }else { sleep 1 } } END: }

    I'm not really a human, but I play one on earth. flash japh
      Thanks, but this is also something I've been doing more or less, but this solution is just making the problem halfsolved so to speak. I mean, the
      $mw->after(1000);
      is there just to make time for the
      &work()
      thread to finnish it's job, so the
      $full_PathMatchEntry->configure(-choices => \@choices);
      will actually change something! This is all nice, but its still not the
      &work()
      that changes the
      $full_PathMatchEntry .
      Maybe this isnt possible as it is now, although I bet there is...
      If we break it down to the main problem, this workaround has to be done since the
      $full_PathMatchEntry
      can't be shared. Now, how about sharing
      @choices ?
      This would all be good, if we didnt had to do:
      $full_pathMatchEntry->show_listbox();
      I mean, here we still need to somehow notify the widget that something has changed (thing is that the change to the @choices can happen, and if we don't type anything more, then we won't resisplay the listbox), but how to do that? We can't have a listener in the Tk thread, since then we can't type anything...
        It's possible to do, but I'm not entirely sure what kind of code you are after? From your description of the problem, I'm guessing you want the @choices available at the listbox to change in main, when the thread adds another element to @choices?

        If so, make @choices shared, and run a timer in main, which saves the old @choices and compares it to the current @choices, and updates the listbox when it detects a difference.

        Alternatively, you could setup a few extra shared variables, one a flag, and one the new entry. When the thread wants to add a new entry to @choices, it sets the flag, and the new data to add.

        Pretty much, either way, you are going to need a timer running in the main Tk thread to periodically check for changes. Tk will not watch across thread boundaries for variable changes, you have to actively read them.

        Another idea, is setup some sort of binding on the listbox, that updates it's selections from @choices, everytime it comes into focus, or when the drop-down-selection list is triggered.


        I'm not really a human, but I play one on earth. flash japh