Don't exit loop when ESC button press

import rhinoscriptsyntax as rs
import scriptcontext as sc

while True:
    Value=rs.GetString("Input:")
    if sc.escape_test(False):
        print "ESC pressed "
        break
    print Value

I run this script in Version 6 SR20 but don’t exit when ESC button press.

1 Like

Do not use ‘while’ in Rhino, ever!
Using ‘while’ will shorten your life. :stuck_out_tongue_winking_eye:

@xiix.xoox, there is nothing wrong using while loops but you should always put your code into a function so you can use return statement in case you want to exit at a certain point and continue the script at another point.

For your example you might just check if a value has been entered, if not break the loop. This also works if you press ESC when it prompts for a value:

import scriptcontext
import rhinoscriptsyntax as rs

def DoSomething():
    while True:
        value = rs.GetString("Enter something:")
        if not value: break
        print "You entered: {}".format(value)

    print "End of loop"

DoSomething()

_
c.

2 Likes

Thank you. I know it must be, but in this case I want the user to enter it.

import rhinoscriptsyntax as rs
import scriptcontext as sc
while True:
    Value=rs.GetString("Input:")
    if sc.escape_test(False):
        print "ESC pressed "
        return
    #if Enter button Pressed
    elif not Value or not Value.isdigit():rs.Rhino.UI.Dialogs.ShowMessageBox("Why not Input?","Note",0,System.Windows.Forms.MessageBoxIcon.Error)
    else:break
print Value

LOL. What can I use now

For

I think that GetString is consuming the Esc keypress.

As @clement says, according to the GetString help doc:

Returns:
  str: The string either input or selected by the user if successful.
       If the user presses the Enter key without typing in a string, an empty string "" is returned.
  None: if not successful, on error, or if the user pressed cancel.

So testing Value for None is equivalent to Esc keypress, (although there may be other ways to make a None return). A Return keypress with no text will give you an empty string, “”, so those two conditions may work for your example. If more explicit flow control is needed then add options to GetString and test for those.

If Rhino gets into a non-responsive state, no ESC will help you.

Use For and spare yourself the trouble.

Can you demo with this?

infinite loop with “for”. Hmm
What are the values of loop

Why would you need infinite?
After 1000 loops Rhino will become non-responsive. (depending on what you do inside that loop)

Better do For _ in range(10000) will have more success, and it is more reliable.

import rhinoscriptsyntax as rs
import scriptcontext as sc

while True:
    Value = rs.GetString('Input: ', None, ['Option_1', 'Option_2'])
    if Value is None:  # empty string will also be 'not', so test for None
        print('maybe Esc was pressed..breaking from loop')
        break
    if Value == '':
        print('Enter pressed with no string')
        continue
    # test for options in same manner...
    print '{} was entered'.format(Value)
1 Like

Thank you!

Thank you to everyone who helped me!

I’ve coded myself into plenty of long running or infinite loops while testing. Sometimes, as you suggest, in order to figure out what is going on, I may change it to a for loop with enough cycles to describe the issue, but there is nothing wrong with a while True loop as long as you have your exit plan in place.

True, there is no built-in way I know of that will kill your script and keep Rhino running if you get into trouble (that would be nice tough). I have used the escape_test in the past with success (sometimes it takes 2 escape presses).

If interested, here are some things I have discovered while dealing with the UX in these situations:

Rhino.RhinoApp.Wait() can help help with ‘not responding’ windows messages, although where to put it seems to be something of an art, to me at least.

Periodic prints, doc updates and sc.doc.Views.Redraw() can also provide feedback in long running loops. Maybe updating every 100 or 1000 or n cycles is more appropriate than every singe loop.

rs.StatusBar#######() functions are available if you can estimate completeness or some other scalar metric. Updating this seems to keep Rhino ‘alive’ pretty well.

Conduits are a little more complex but are another way (my favorite) to provide graphical updates on loop progress as well, if the loop is updating/generating geometry.

2 Likes

Thank you. I will learn more

Sometimes is the key word here. I don’t like to have a solution that might work.

Yes, I know, I’ve tried them all. But they slow the solution.

In my experience While loops lead to crash in most cases. This should not be programmer’s luck. Rhino should be made in such a way to prevent non-responsive-ness. Also sometimes rhino goes into a RAM-killing frenzy that leads to system crash. That’s also Rhino issue. Since 3DExperience doesn’t do that and it’s a monster of a software. I do not accept this is an error of the script (the user). Just that Rhino is not developed to protect PC’s resources and to ensure Windows has enough resources to allow the user to kill Rhino when necessary.