Beefy Boxes and Bandwidth Generously Provided by pair Networks
There's more than one way to do things
 
PerlMonks  

Gtk2-Perl: Waiting for particular event

by Bloehdian (Initiate)
on Mar 23, 2013 at 17:49 UTC ( #1025054=perlquestion: print w/ replies, xml ) Need Help??
Bloehdian has asked for the wisdom of the Perl Monks concerning the following question:

Hello folks,

I am not quite sure whether the solution to the problem described below which I intend to implement is, firstly, feasible and, secondly, could be done in a less cumbersome way, potentially using "built-in" features of Gtk.

The problem:

I created a GUI which, when the user wants to save his work, presents the user a summary in a notebook page which has to be accepted or rejected ("Ok" and "Cancel" button at the bottom of the page) by the user prior to the actual saving . Most of the GUI is deactivated at this point, but a few buttons and the notebook page with the results to be saved stay active, i.e., a part of the GUI stays responsive while waiting for the user to press one of the two buttons (it could be necessary for the user to switch to the other notebook page prior to proceed with saving; if any other button is pressed apart from the both mentioned the user will be asked to only press "Ok" or "Cancel" since this is the only way to proceed with the application).

On the code level this means that the application should wait within the _save_work() subroutine for a 'button-press' event and, when it was passed to either the "Ok"-button or the "Cancel"-button, the program should execute the necessary actions and leave the loop. If any other event will occur the application should stay in that loop to force the user to press one of the buttons.

The code fragments I have in mind look as follows (for the sake of simplicity I present it only for the "Ok"-button, "Cancel"-button should be analogous):

... use Scalar::Util; use Glib qw(TRUE FALSE); ... sub _init { ... # Creating the "Ok"-button $button_ok = Gtk2::ToolButton->new( undef, 'Ok' ); $self->{ButtonOk} = $button_ok; # Connecting the signal-handler to it $button_ok->signal_connect( 'clicked' => sub { $self->_ok_pressed( @_ +) } ); } # The signal handler sub _ok_pressed { my ( $self, $button, $event ) = @_; # Make button and event object properties to have them available ou +tside the # signal handler's scope $self->{EventHash}->{Button} = $button; $self->{EventHash}->{Event} = $event; # Clear the summary, navigate to other notebook page ... } # The _save_work subroutine sub _save_work { # Parameter processing, declarations, etc. ... # The actual loop which waits for the event while ( TRUE ) { # Give the main loop the chance to intercept events with the +program # being in this loop while ( Gtk2->events_pending() ) { Gtk2->main_iteration(); } if ( %{$self->{EventHash}} ) { # This checks whether the expected TYPE of event ocurred and wheth +er it # was passed to the expected WIDGET (the "Ok"-button) if ( ( refaddr( $self->{EventHash}->{Button} ) == refaddr( $self->{ButtonOk} ) ) && ( defined( $self->{EventHash}->{Event}->{'type'} ) + ) && ( $self->{EventHash}->{Event}->{'type'} eq 'button +_press' ) && ( $self->{EventHash}->{Event}->{'button'} == 1 ) ) + { # Code executed after pressing the "Ok"-button goes here ... $self->{EventHash} = (); last; } } } }

To me, this approach seems a little bit cumbersome (and, consequently, not very readable)

Any suggestions for a more straightforward solution to the problem?

Greetz

Bloehdian

Comment on Gtk2-Perl: Waiting for particular event
Download Code
Re: Gtk2-Perl: Waiting for particular event
by moritz (Cardinal) on Mar 23, 2013 at 18:15 UTC
    On the code level this means that the application should wait within the _save_work() subroutine for a 'button-press' event and, when it was passed to either the "Ok"-button or the "Cancel"-button, the program should execute the necessary actions and leave the loop. If any other event will occur the application should stay in that loop to force the user to press one of the buttons.

    Somehow "looping and waiting" makes me uneasy, because you are already in an event loop that is responsible for looping and waiting.

    So another approach would be to have the code register a callback for the "Ok" and one for the "Cancel" button, disable most of the widgets, and then return.

    Then the event handlers for the "Ok" and "Cancel" buttons are responsible for calling the callbacks that the code we first talked about registered.

      Hi moritz,

      > Somehow "looping and waiting" makes me uneasy, because you

      > are already in an event loop that is responsible for

      > looping and waiting.

      I was aware of the main loop issue, but I thought that this would be "healed" with the call to the Gtk->events_pending function. Isn't it like that?

      Not using the "waiting for event" approach would, at least, have the consequence not having a "closed" _save_work method any more, which does all the stuff, but several independent functions which would conceal the application's logic, i.e., this would make it harder to understand the code.

      So, I would like to stick to the "wait" approach if ever possible.

      Cheers

      Bloehdian

        Not using the "waiting for event" approach would, at least, have the consequence not having a "closed" _save_work method any more, which does all the stuff, but several independent functions which would conceal the application's logic, i.e., this would make it harder to understand the code.

        There's a reason one usually doesn't have one function which does "all the work". Afaict _save_work should just, well, save the work, not do UI teardown and other stuff. Doing one thing per function usually increases readability, not decreases it.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1025054]
Approved by moritz
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chilling in the Monastery: (7)
As of 2014-09-30 23:08 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    How do you remember the number of days in each month?











    Results (385 votes), past polls