Beefy Boxes and Bandwidth Generously Provided by pair Networks Frank
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Perl GTK2 with Perl Threads

by sam_bakki (Monk)
on Jun 08, 2011 at 12:00 UTC ( #908692=perlmeditation: print w/ replies, xml ) Need Help??

Hi Great Monks,

perlmonks.org is a great place for perl lovers to learn and share. I have learn many things from this site, Now I am here to share.

A month ago, I started looking for GUI development in perl. Since I was familer with Visual Basic , I also wanted good GUI editor and latest , stable tool kid. Based on many other criterias, I chose Perl GTK2.
With using Gtk2::GladeXML, You can create simple GUI applications so fast but real problem arise when you have an application with Threads.
Since Perl threads and perl Gtk2 will not go better , I had to dig out a lot for making things work.


1. Never create / Call any GTK2 objects in perl threads.
2. Re structure you app in such a way that , IN main thread you will create GTK2 objects and in other threads should do some work and put the results in some Q
3. Using GLib::Idle->add(), you can keep pool the result Q and update the GUI.
4. use Thread::Queue

This model works very well for me. I have created web spider application (initial version but working condition) with GTK2 GUI front end.

http://code.google.com/p/saaral-soft-search-spider/

Since it is big code (with 2 modules), I do not want to paste it here.

Please see : http://code.google.com/p/saaral-soft-search-spider/source/browse/#svn%2Ftrunk

Thanks
Bakkiaraj M

Comment on Perl GTK2 with Perl Threads
Re: Perl GTK2 with Perl Threads
by zentara (Archbishop) on Jun 08, 2011 at 15:07 UTC
    Hi, the whole topic of running threads with GUI's in Perl gets very complicated, but I will take issue with your assertion

    1. Never create / Call any GTK2 objects in perl threads.

    Gtk2 has done much work to make thread safety work, but it is still tricky, and as you say, using GLib::Idle->add() is the way to go. Just to show this is true, here is an example where Gtk2 widgets are Called, but not created, from a thread. It works fine.

    #!/usr/bin/perl use warnings; use strict; use threads; use threads::shared; use Glib qw/TRUE FALSE/; use Gtk2 qw/-init -threads-init/; Glib::Object->set_threadsafe (TRUE); #setup shared hash my %shash; share(%shash); #will work for first level keys $shash{'go'} = 0; $shash{'work'} = ''; $shash{'die'} = 0; my $window = Gtk2::Window->new('toplevel'); $window ->signal_connect( 'destroy' => \&delete_event ); $window->set_border_width(10); $window->set_size_request(300,300); my $vbox = Gtk2::VBox->new( FALSE, 6 ); $window->add($vbox); $vbox->set_border_width(2); my $hbox= Gtk2::HBox->new( FALSE, 6 ); my $hbox1 = Gtk2::HBox->new( FALSE, 6 ); $vbox->pack_end($hbox,FALSE,FALSE,0); $vbox->pack_end (Gtk2::HSeparator->new, FALSE, FALSE, 0); $vbox->pack_end($hbox1,FALSE,FALSE,0); $hbox->set_border_width(2); $vbox->pack_end (Gtk2::HSeparator->new, FALSE, FALSE, 0); my $ebutton = Gtk2::Button->new_from_stock('gtk-quit'); $hbox->pack_end( $ebutton, FALSE, FALSE, 0 ); $ebutton->signal_connect( clicked => \&delete_event ); my $pbar = Gtk2::ProgressBar->new(); $pbar->set_pulse_step(.1); $hbox->pack_start($pbar,1,1,0); my $count = 0; my $label_w_markup = Gtk2::Label->new(); $label_w_markup->set_markup("<span foreground=\"yellow1\" size=\"40000\">$count</span>"); $vbox->pack_end($label_w_markup,FALSE,FALSE,4); ###################################################### my $tbutton = Gtk2::Button->new_with_label('Run Thread'); $hbox1->pack_start($tbutton , 1, 1, 0 ); my $lconnect = $tbutton->signal_connect( clicked => sub{ launch() }); my $sconnect; $window->show_all(); $pbar->hide; #needs to be called after show_all #create 1 sleeping thread passing it the label and pbar to control my $thread = threads->new(\&work, $label_w_markup, $pbar); Gtk2->main; ###################################### sub delete_event { $shash{'go'} = 0; $shash{'die'} = 1; $thread->join; Gtk2->main_quit; return FALSE; } ####################################### sub launch{ $pbar->show; $tbutton->set_label('Stop Thread'); $tbutton->signal_handler_block($lconnect); $sconnect = $tbutton->signal_connect( clicked => sub{ stop() }); $shash{'go'} = 1; } ################################################## sub stop{ print "stopped\n"; $shash{'go'} = 0; $pbar->hide; $tbutton->set_label('Run Thread'); $tbutton->signal_handler_block ($sconnect); $tbutton->signal_handler_unblock ($lconnect); } ##################################################### sub work{ my ($label,$pbar) = @_; $|++; while(1){ if($shash{'die'} == 1){ return }; if ( $shash{'go'} == 1 ){ foreach my $num (1..1000){ Glib::Idle->add( sub{ if($shash{'die'} == 1){ return }; $label->set_markup("<span foreground=\"yellow1\" size=\"40000\">$num</span>"); $pbar->pulse; return FALSE; }); select(undef,undef,undef, .1); if($shash{'go'} == 0){last} if($shash{'die'} == 1){ return }; } $shash{'go'} = 0; #turn off self before returning }else { select(undef,undef,undef,.1) } #sleep time } return; } ###########################

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

      Hi Zentara
      I already had a look in to this example perl application. I am on windows XP with Activeperl 5.10. For some reason,  use Gtk2 qw/-init -threads-init/; crashes, I had to use only  use Gtk2 qw/-init/; .
      More over, Label update in this example application (which updates 1..2..3 in yellow color) stops update after 38 or 40 or some time after 50. So I would say this method is not reliable in Windows (atleast , need to check in Linux).
      Also i wanted very fast gui updates, If you run my application you will see how fast it updates Text Buffers.
      Thanks

Re: Perl GTK2 with Perl Threads
by Anonymous Monk on Jun 09, 2011 at 01:54 UTC

      Hi Monk

      I am using ActivePerl 5.10 on Windows XP.
       use Gtk2 qw/-init -threads-init 1.050/;
      is crashing. So I had to use
      use Gtk2 qw/-init/; <br. Also when I run the example (thread_usage.pl) (Which I already had look out), It produces many warnings in GTK. So I developed a clean solution.
      Thanks for sharing links, I already had look in to all the links. Nothing works well for me in windows. So After learning lot, I created project in google code so others can have a look at it.

        Nothing works well for me in windows

        Well then, get yourself a REAL operating system. :-)


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

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlmeditation [id://908692]
Front-paged by Arunbear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (7)
As of 2014-04-20 19:22 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (486 votes), past polls