What is the most efficient way to wait for an image to appear or vanish?

Asked by andrea

Hi,
I would like to know the more efficient way in sikuli to wait for an image to appear or vanish on the screen.
Here what I have been trying for image appear

while region.exists("mypicture.png"):
        pass
Loop until the image does appear on the region.
and

region.onAppear(image, myHandler)
 region.observe(FOREVER) # observes until stopped in handler

Observe until the image appear on the region

What is the most efficient? there is another way to do it.?

Thanks
Andrea

Question information

Language:
English Edit question
Status:
Answered
For:
SikuliX Edit question
Assignee:
No assignee Edit question
Last query:
Last reply:
Revision history for this message
RaiMan (raimund-hocke) said :
#1

If you are sure the image will ever come or vanish:

wait("image.png", FOREVER)

or

waitVanish("image.png", FOREVER)

If the expected situation does not come, the script will loop forever.

Revision history for this message
Dale R Mcgeachie (dmcgea) said :
#2

Hi thx for quick reply, this is my code -

switchApp("Myapp")
while not exists("desktop", ): # myapp is windowed, full screen, hiding desktop, therefore always loop
setThrowException(False) # get rid of not found errors
type("mykey") # this triggers random appearance of icon
sleep(13) # workaround to wait for icon changing to second state - icon_1st_state appears randomly and then changes after a random amount of time between 1 - 15 seconds
Region(Region(myregion)).inside().rightClick(Pattern("icon_1st_state").similar(0.47).targetOffset(-11,9)) # click it
hover("mouseoutofway") # move mouse to a corner of screen - icon somtimes appeared under mouse

I need to be able to rightclick the icon exactly when it changes to its second state, and I need the program to run constantly, as it is it works, but it would be better if caught the change to the icons second state. I was thinking of using lastmatch and setting the search region to where the icon is found and using onchange? to detect the change to the icons second state. thx :)

Revision history for this message
Dale R Mcgeachie (dmcgea) said :
#3

oooops sry posted this to wrong message :)

Revision history for this message
RaiMan (raimund-hocke) said :
#4

before looping around, you should try to get your main issue resolved: tracking the icon.

You could use onChange/observe, but my experience is, that only in asynchronous situations (observe in background, while the main script keeps running), the additional effort to get it running pays back.

So for inline waits (synchronous), in my opinion, using exists(image, 0) (searches only once) is the most flexible and efficient way.

example: (only the icon workflow once)

icon_start = "image of the original icon"
# this should have as little background as possible

myreg = "a region, where we expect the icon to appear, as small as possible"

type("mykey") # this triggers random appearance of icon

# first we wait for the icon, to get its region on the screen
mIcon = wait(icon_start, 20) # its an error, if it does not appear after e.g. 20 secs, script should stop then
mIcon.highlight(1) # to show, where we found it (debug only)

# now we look for the icon to change
# we look in the region of the icon with the start icon image
while mIcon.exists(Pattern(icon_start).similar(0.99)), 0):
    pass # search continuously
    # or wait(1) to search once per second

# this loop will end, if it is sure, that the icon will change at some time
# an alternative with a max wait time, see below

# now we can click
rightClick(mIcon.getCenter().offset(11,9))

--- comment on setThrowException(False)
I do not recommend this. If you want a find operation to be processed anyway, use exists()
Then you can use find and wait in situations, where the visuals should be found normally, but not found is exceptional and should terminate the script, because it would not make any sense to proceed.

e.g.

click("image") # would error if not found
click(exists("image")) # would do nothing if not found

--- an alternative with a max wait time

max = 50 # seconds
found = False
start = time.time()
while mIcon.exists(Pattern(icon_start).similar(0.99)), 0):
    wait(1) # to search once per second
    if time.time()-start > max: break
else:
   found = True

if not found: print "we should stop here"; exit()
# normal workflow proceeds

Can you help with this problem?

Provide an answer of your own, or ask andrea for more information if necessary.

To post a message you must log in.