sush has asked for the wisdom of the Perl Monks concerning the following question:

Hi Monks,
I have a GUI application (written in wxPerl) which calls other processes (mostly perl scripts) based on user selection.
If user selects all processes and clicks Start P1 ... PN is called in sequence.

Question 1
-How do I disable (gray-out) some other buttons when button A is selected. I also want to ensure if button is clicked more than once, event occurs only once.
Right now I am setting a global variable flag to see if/which button is clicked. It seems a primitive way to do it.

Question 2-
-The application needs to provide user control to Pause after current process finishes and before it kicks off the next process. The problem I am having is that Once Start Button is clicked control is handed over to the subroutine called and until the sub doesn't return, the GUI does not process any other events.

So how do I make event A run in background and return to GUI's main Loop so it can process other events.


Any Help is very much appreciated.
The relevant part of code is given below:
##All GUI defining.layout stuff here # EVT_BUTTON ($self, $start_btn, \&runProcess1, ); EVT_BUTTON ($self, $pause_btn, \&runProcess2, ); sub runProcess1{ my ($self, $event)= @_; if (!$MyFrame::startIsClicked){ &MyMethods::testStartJob($self,$event); } } sub runProcess2{ my ($self, $event)= @_; $| =1; print "This is the pause event \n"; }
Thank you Wise Monks, I work to fork now...

Replies are listed 'Best First'.
Re: wxPerl Event Handling/GUI process control
by zentara (Cardinal) on Nov 19, 2007 at 20:35 UTC
    I don't use Wx, but I can give some general guidance based on how other guis work, like Tk or Gtk2.

    As far as the first question goes, normally you put a statement to set the state of the button to "disabled", at the beginning of the callback. Then return the state to "normal" at the end of the callback. When the state is disabled, a button will appear to be greyed out. You can disable all buttons, if they are global variables, by setting all their states. The callback will not be called when the button is disabled.

    The second question, indicates you are blocking the event loop, but you don't really show any code. Gui's, in general, don't like "sleep" statements, or running commands thru system. If you run a command thru system, it takes complete control over the program until it finishes, then it returns control to the gui's event loop. During the period, where the event loop has lost full control, it will be unresponsive; unless you call frequent "updates" (whatever Wx calls them).

    Generally, if you want a responsive gui, while you run external programs, you fork and run them in the forked process; OR you run them in threads. But this is all complex, and needs a couple of chapters to explain. You can use the SuperSearch here, or groups.google.com for examples of fork-and-exec or using threads in Perl.


    I'm not really a human, but I play one on earth. Cogito ergo sum a bum
Re: wxPerl Event Handling/GUI process control
by gloryhack (Deacon) on Nov 20, 2007 at 05:40 UTC
    Coincidentally, I just implemented this very thing with Wx just last week.

    Just use IPC::Run to fork your runProcess1() and return control to Wx::MainLoop. To effect a pause rather than a stop, you'll probably want to use signals (IPC::Run::signal) rather than IPC::Run::kill_kill to terminate the detached process. Maintaining state "is left as an exercise to the reader" :-)

    Because your runProcess1() will be detached and the Wx GUI functional, you'll want to disable any GUI elements that could do things that might change the environment of the background process in an undesirable way.

    Wow, two plugs for IPC::Run in one day... and I don't even know the author!

Re: wxPerl Event Handling/GUI process control
by Anonymous Monk on Nov 20, 2007 at 08:59 UTC
    The demo has examples