On May 13, 2009, at 10:32 AM, 唐瑞博 wrote:
For the gdk lock method, I have used Gtk2::Gdk::Threads->enter and Gtk2::Gdk::Threads->leave in my background thread, it seem that it can update all the widgets(like button, labes) correctly excepte the Gtk2::TreeModel(I used a Gtk2::ListStore actually). when i use the Gtk2::TreeModel->set() method, it will fail and says "Usage: Gtk2::TreeModel->set($liststore, $iter, $col.....)" , and then the exit. I checked my code and found that I have a column with type Glib::Scalar in my treemodel, in this column i assign a pointer to an new constructed object ( the object is not a subclass of Glib::Object, and have not decleared as shared), I do not know if the fail have relationship with this object?
This certainly smells like you're running afoul of perl threading. Run away!
For the Glib::Idle method method, I put Glib::Idle->add (\&update_treeview, $tid) to my background thread, and it appear the same error as first method. According to your reply, i think the update_treeview should be run in the Main thread, but after my check, i found it runs in the background thread actually, so when the background thread access the Gtk2::TreeModel->set, it will fail as the first method.
A quick test with glib in C shows that calling g_idle_add() on a background thread causes the main loop on the main thread to execute the callback.
But a similar test in perl, using threads->self->tid(), shows the same thread executes everything. Something is up. We're probably using the wrong context when executing callbacks for the main loop. However, i'm not sure how we would differentiate. Hrm.
(Files attached.)
#!/usr/bin/perl -w use Glib; Glib::Object->set_threadsafe (1); use threads; sub callback { print "callback on ".threads->self->tid()."\n"; 0; } my $loop = Glib::MainLoop->new; sub background { sleep 1; print "queuing callback on ".threads->self->tid()."\n"; Glib::Idle->add (\&callback); sleep 1; print "queuing callback on ".threads->self->tid()."\n"; Glib::Idle->add (\&callback); sleep 1; print "queuing mainloop kill on ".threads->self->tid()."\n"; Glib::Idle->add (sub { print "killing mainloop on ".threads->self->tid()."\n"; $loop->quit; 0; }); } my $thread = threads->create("background"); print "running mainloop on ".threads->self->tid()."\n"; $loop->run; $thread->join;
loop.c
Description: Binary data
Run away! (At least until we figure it out.)
For the third method, i used a Thread::Queue as pipe, the background thread enqueue the need updated data to the pipe, in my main thread, i use Glib::Timeout->add(1000, \$update_treeview) to update my GUI, every 1 second will to update the GUI, in this method I access the Gtk2::TreeModel->set in the Main thread, so the error does not appears. And all works well. Although update UI is not realtime, also can acceptable. I do not know if there are any better solutions for my issue or if there is any improvement for this method?
If you use an io watch to monitor the pipe, instead of a 1 second timeout, then the updates will be roughly as fast as the data shows up.
-- Sallah! I said no camels! That's five camels! Can't you count? -- Indiana Jones
_______________________________________________ gtk-perl-list mailing list gtk-perl-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-perl-list