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

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

Replies are listed 'Best First'.
Re^5: Annoying threads share problem!
by Ace128 (Hermit) on Oct 10, 2005 at 04:30 UTC
    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
        Yea, this is the current solution. I have some flag that the main (tk) thread checks every 20 ms or so... updates @choices when flag set.. Although I would prefer that the searchUpdate thread notified the main thread somehow, this works just fine. But seems like such a CPU waste (although its not many instructions... some jump and a check and jump back).