About Treeview update with thread



hi,
In my project, The GUI have a treeview and a 'Run' Button,Treestore may have thourands of datas.
 
When i click the 'Run' button, the logci will process the treestore datas one by one(this is a long time procedure), when one data process complete, i need to update the Treeview immediately.
 
In order to avoid the GUI lag, I use a thread to do the backend processing. The problem is when the thread to update the Treeview, the logic will fail.
 
below is my code snapshot,
 
GUI.pm

use Gtk2 qw/-init -threads-init/;
Glib::Object->set_threadsafe (TRUE);
 
$runBtnClicked = sub {
 
    # get the user selected cases from the treeview
    my $caselist  = [];
    my $model = $treeview->get_model;
    my $iter = $model->get_iter_first();

    while(defined($iter)){
        if($model->get_value($iter, COLUMN_SELECT)){
            push @$caselist, $model->get_value($iter, COLUMN_CASEOBJ);
        }
        $iter = $model->iter_next($iter);
    }
 
    # caserunner is used to process the tree store datas
    my $caserunner = Test::CaseRunner->new;
 
     # GUI register to the caserunner as a onecasecomplete event listener
    # then when process one tree store data complete, caserunner will notify GUI to update treeview
 
    $caserunner->addOneCaseCompleteListener($this);

    # use a thread to process the datas
          my $thread = threads->new(sub {
                    my ($cr, $cl) = @_;
                    $cr->runCase($cl);
                    },$caserunner,$caselist);
}
 
 
sub oneCaseComplete {
 
my ($this, $tid) = @_;
 
my $iter = $this->{caseiters}->{$tid};
my $case = $model->get_value($iter, COLUMN_CASEOBJ);
my $model = $this->{widgets}->{treeview}->get_model;
 
# update the TreeView
$model->set($iter,COLUMN_STATUS, $case->getRunResult);
$model->set($iter,COLUMN_TIME, $case->getUsedTime);     // when run to here, logic fails and the entire process exit  abnormally,  the message says" Usage: set(list_store, iter, col1, val1...) at..." . 
}
 
 
CaseRunner.pm
 
sub runCase {
     # use a loop to process the caselist one by one, a long time process
 
     foreach $oneCaseStr ( @$caselist ) {
                      ...........
        # one data process complete, notify the GUI to update the treeview
        $self->$fireOneCaseCompleteEvent($oneCaseStr->getTid);
    }
}

sub addOneCaseCompleteListener {
     my ($self, $listener) = @_;
     my $listeners = $self->{listeners};
     if(defined($listener)){
        push @$listeners, $listener;
    }
};

$fireOneCaseCompleteEvent = sub {
    my ($self, $tid) = @_;
    my $listeners = $self->{listeners};
 
    # notify the listeners one by one
    # Note: all listeners must have a method "subPaneSelected"
    foreach my $listener (@$listeners) {
        $listener->OneCaseComplete($tid);
    }
};

 
I have try with no thread used, the logic is correct, but the GUI lag, and it is not acceptable. 
 
Can any one tell me why it fails, or give some suggestion for how to update the GUI in a thread.
 
Thank you very much!!
 
Ruibot


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]