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

Greetings!

I have a problem with my new script. It prints questions on screen so an operator can anwser. After the anwser is entered, sleep() function turns on so the operator needs to wait before anwsering to another question.

The problem is that he can type during that sleep time so I'd like to disable the keyboard input during that period.

Does anyone know any solution?

Replies are listed 'Best First'.
Re: Disabling keyboard input
by Perlbotics (Archbishop) on Aug 09, 2011 at 13:47 UTC

    You need to clear the input buffer before reading the next response.
    Maybe this module does already cover all your requirements? IO::Prompter or Term:UI

    Update: The following method clears the input buffer (at least on Unix):

    use Term::ReadKey; sub flush_stdin { ReadMode 4; ReadLine(-1); ReadMode 0; } sleep 5; # type 'something' flush_stdin(); $|=1; print "---> "; chomp (my $answ = <STDIN>); print "answ: ($answ)\n"; # w/o 'something'

    Update: Cannot test it under Windows, but maybe Win32::Console works (see Flush() method)?

      Thanks!

      I'm currently trying to explore this method although I'm not skilled enough yet, so it will take me some time

      Thanks again for your help!

      Thanks for your solution!

      Unfortunately, I use Windows and it doesn't work

Re: Disabling keyboard input
by moritz (Cardinal) on Aug 09, 2011 at 14:11 UTC

    Are you trying to make life harder for the user, or is there a specific reason why you sleep and want to prevent early input? Maybe there's a better solution to you overall problem.

      Yes, there is a reason.

      Operator needs to do a specific task during that pause so only after finishing the task he can acullay fill in the result. So sleep function is required to encourage him to do his job properly.

        I obviously don't have enough information to be sure, as you're being quite vague (probably for good reason). But a lack of information rarely prevents me from chiming in :-)

        I have done the install software for more than one application over my career so far (I'm not saying that's what you're doing). While many in upper levels of management think "install" == "copy files, how hard can that be?", we took it as much more than that. Initial configuration has always been part of it. That is, we ask a bunch of questions which then tell us how to deploy. And here is where we get to what is likely relevant to you: we ask all questions up front only, and perform all actions after that completely automated. Don't make the user come back from a coffee break only to find that the activity is incomplete, waiting for their input. Allow them to go on their coffee break and come back to a completed activity.

        This often means that you need to automate more stuff. That's always a good thing, in my mind. It is more work up front, but generally pays for itself quickly. Sometimes in a year, sometimes in a week. And it generally improves quality: once you get the automation tweaked properly, it won't make typos or forget steps, like a human is apt to do (especially this human who is far too lazy and egocentric to do mindless stuff repeatedly).

        Maybe this isn't something that you know how to automate yet. And so, for now, you continue to harass the operator for information. In that case, I'd make a couple of suggestions. First off, don't annoy the operator any more than you already have to. Don't sleep. Don't ignore stuff she has already typed. Because the operator may already know what is next, and is likely smarter than your program.

        Second, your goal should not be further harassment, but further automation. Design decisions should be based on making things as painless for humans as reasonably possible, and eliminating error. Free the operator from the mundane things that computers can do so they can do higher-value things for the company, such as analysis or Sarbanes-Oxley compliance. (Sorry - that last one isn't high value for the company as much as for the public and/or politicians.)

        maybe it will be better to log time between responses and analyze them later

        While I'm not at all convinced (hey, if he can only fill in the result after getting the result, why do you need to wait?), I'd suggest looking into bindings for curses, at least on Unix-y systems.

Re: Disabling keyboard input
by zentara (Cardinal) on Aug 09, 2011 at 21:36 UTC
    Can you use Tk or even Tkx? If so, it would be very simple to make an Entry widget to accept input, then have the screen change to red while a countdown timer ticked of the time delay. The Entry would be inactivated, essentially discarding all keyboard input. When the delay hit 0, it would return the screen to green, and allow another input into the Entry. The cycle then repeats.

    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh
Re: Disabling keyboard input
by Khen1950fx (Canon) on Aug 09, 2011 at 22:14 UTC
    Here's my solution. Both of the answer sequences have a 10 second delay, and both of the sequences are invisible. It requires Prompt::ReadKey::Sequence.
    #!/usr/bin/perl use strict; use warnings; use Prompt::ReadKey::Sequence; use English qw(-no_match_vars); use Term::ReadKey qw(ReadMode ReadKey); local $OUTPUT_AUTOFLUSH = 1; my $seq = Prompt::ReadKey::Sequence->new; $seq->run; Press_key(); Press_key_again(); sub Press_key { open my $tty, '<', '/dev/tty'; print "Press a key: \n"; ReadMode(2); ReadKey(10, $tty); ReadMode('raw'); my $key = ReadKey(10, $tty); printf "\nYou said %s, char number %03d\n", $key, ord $key; ReadMode('normal'); } sub Press_key_again { open my $tty, '<', '/dev/tty'; print "Press key again: \n"; ReadMode(2); ReadKey(10, $tty); ReadMode('raw'); my $key = ReadKey(10, $tty); printf "\nYou said %s, char number %03d\n", $key, ord $key; ReadMode('normal'); }