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

I wrote the following bit of code using Tk:
use strict; use Win32::Clipboard; use Tk; my $change_mode = \&change_mode; my $mode = 0; my $clip = Win32::Clipboard(); my $main = new MainWindow; $main->Label(-text => 'Clipboard Case Changer' )->pack; $main->Button(-text => 'On/Off Toggle', -command => $change_mode )->pack; MainLoop; sub change_mode { $mode = !$mode; } #Change clipboard contents to uppercase, if $mode == 1; while(1) { $clip->WaitForChange(); my $contents = $clip->Get(); if ($mode) { $clip->Set(uc($contents)); } }
Even though I'm new to Tk, I was pretty sure the above code wouldn't work. Sure enough, it doesn't. I'm guessing it's because the infinite loop, outside of the 'MainLoop,' never gets executed. So am I going to need a thread here? I've dabbled with threads in Java. But I'm not familiar with threading at all with Perl and I hear it's kind of a nightmare. Is there a more obvious technique I could be using that I'm missing?

$PM = "Perl Monk's";
$MCF = "Most Clueless Friar Abbot Bishop Pontiff";
$nysus = $PM . $MCF;
Click here if you love Perl Monks

Replies are listed 'Best First'.
Re: Does this Tk program require a thread?
by bobn (Chaplain) on Jul 15, 2003 at 00:52 UTC

    In "Mastering Perl/Tk", pg 402, they discuss a $mw->repeat function. From looking at it briefly, it loks like you want:

    $main->repeat(50 => \&run) MainLoop; sub run { $clip->WaitForChange(); # needs to NOT block. my $contents = $clip->Get(); if ($mode) { $clip->Set(uc($contents)); } }
    EBut this is suposed to be a non-blocking routine, as run will be called every 50 milliseconds, so you need to rewrite that part to see if there's new clipboard content and return if not. If it blocks, MainLoop stops running.

    ALthoough --Bob Niederman, http://bob-n.com

      Not elegant by a long shot but it did the trick. Thanks for looking that up.

      $PM = "Perl Monk's";
      $MCF = "Most Clueless Friar Abbot Bishop Pontiff";
      $nysus = $PM . $MCF;
      Click here if you love Perl Monks

        And, in case you haven't already looked it up, WaitForChange() accepts a millisecond time-out parameter. So, you can call $changed = $clip->WaitForChange(1); to get a "non-blocking" wait.

        bbfu
        Black flowers blossom
        Fearless on my breath

        You might also want to take a look at the Tk::After POD and the other methods it provides in addition to repeat() (like after(), afterIdle(), etc.).

        Also of interest would be waitVariable() and the other wait* methods (see Tk::Widget).