http://www.perlmonks.org?node_id=1055295

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

Hi
is there any mechanism to prevent a perl tk window from hanging. Upon pressing some button on the gui window , it performs lot of other things and the gui goes to a hanging state during this time until the sub routine executed by the button command is finished.
Is there any way to keep the widgets (for example buttons, scrollbar, menu)on the gui still usable so that one can still manage the gui by scrolling etc during that time.

Replies are listed 'Best First'.
Re: perl tk mainwindow hangs
by mtmcc (Hermit) on Sep 23, 2013 at 14:46 UTC
    perl Tk runs in a single thread, so if you process a lot of information in a subroutine, the GUI will seem frozen until the subroutine passes back to Mainloop.

    One way around this is with threads. Although Tk itself isn't thread-safe, there are ways to do it. Have a look at this, for example: Perl/Tk threading and/or cron job?

    I hope that helps!

      Hi ,
      Thanks for the reply
      Actually due to some limitations, I can not use threads.
      Was reading about MainWindow doOneEvent(), but not sure how can that be implemented. Can anybody please give any idea ?

        I can not use threads.

        Why not?


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority".
        In the absence of evidence, opinion is indistinguishable from prejudice.
Re: perl tk mainwindow hangs
by bulk88 (Priest) on Sep 24, 2013 at 03:37 UTC
    Since you say you cant use ithreads, you have to break the CPU heavy (I hope the reason your blocking is CPU, and not IO, since IO can be made async with a medium amount of work) workload into chunks, or during the work, every 100 ms poll to the GUI event loop for the event loop to service pending GUI events.

      Hi ,
      Can you please give some coding hints of how to poll the GUI event loop to serve the pending GUI events ?

        $widget->update;
        لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: perl tk mainwindow hangs
by kcott (Archbishop) on Sep 24, 2013 at 04:41 UTC

    G'day simonz,

    Welcome to the monastery.

    That's actually a rather vague question; however, the mechanism you're probably looking for is the callback (see Tk::callbacks).

    A Tk application is event-driven. You don't write code that waits for some event to occur (or complete), you associate a callback with the event which is called when that event occurs (or completes). Here's some examples:

    • Don't wait for entries to appear in a log file (e.g. "while (<$log_fh>) {...}"). Associate a Tk::fileevent callback with the event of the log file having data to read (e.g. "$mw->fileevent($log_fh, 'readable', $callback)").
    • Don't use a sleep statement to delay doing something until the sleep completes (e.g. "sleep $secs; do {...}"). Associate a Tk::after callback with the completion of the delay (e.g. "$mw->after($millisecs, $callback)").
    • You can use Tk::bind to associate callbacks with all sorts of keyboard, mouse and GUI activities.
    • The -command option of Tk::Button (and similar widgets) takes a callback as its value.

    If the processing involved with a callback takes an inordinate amount of time to complete, then you may need a separate process so that the Tk process doesn't block. That could involve threads or forking a child process (see perlipc). Here's a fairly straightforward way of forking a long running process, using open and Tk::fileevent, that won't block while waiting for the child process to return output:

    open my $pipe, '-|', 'long_running_process.pl'; $mw->fileevent($pipe, 'readable', $callback);

    As I said at the start, your question is rather vague. The information I've provided here should be sufficient for dealing with the usual culprits. If you're having difficulty with a particular problem that I haven't addressed, post specific information and we can look at it. If you do need to post a follow-up question, please follow the guidelines in "How do I post a question effectively?": a better question gets better answers.

    -- Ken