Beefy Boxes and Bandwidth Generously Provided by pair Networks
P is for Practical
 
PerlMonks  

Perl GTK2 with Perl Threads

by sam_bakki (Pilgrim)
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 having an uproarious good time at the Monastery: (11)
As of 2015-07-07 12:25 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    The top three priorities of my open tasks are (in descending order of likelihood to be worked on) ...









    Results (88 votes), past polls