如何打破 python 中自定义 class 方法的 while 条件?

how to break a while condition for a customized class method in python?

我正在尝试使用库 pyautogui 检测按钮,想法是当检测到按钮时只打印迭代试验,当最终检测到按钮时只打印按钮的位置使用 pyautogui.locateOnScreen() 按钮并中断迭代。

但是,下一个代码会永远评估第一次迭代 (0),它永远不会评估后续的 if 条件:

import pyautogui
import os

def button_detector():
    for i in range(450):
        some_button=pyautogui.locateOnScreen(os.path.join(ROOT_DIR, r'some_button.png'), region=(0, 510, 547, 153) , grayscale=False)
            
        while some_button is None:
              print('Button not found at trial {}'.format(i))
              print('Error: did not find any button')
                     
              if some_button is not None:
                 print(some_button)
                 print("Button detected")
                 break

我怎样才能打破 while 条件来完成这个任务?

还有其他更简单的方法吗?

我不知道你为什么使用 forwhile 但对我来说应该是 if/else 而不是 while 和嵌套 if

import pyautogui
import os

def button_detector():
    path = os.path.join(ROOT_DIR, 'some_button.png')
    
    for i in range(450):
          some_button = pyautogui.locateOnScreen(path, region=(0, 510, 547, 153) , grayscale=False)
        
          if some_button is None:
              print('Button not found at trial {}'.format(i))
              print('Error: did not find any button')
          else:       
              print(some_button)
              print("Button detected")
              break
 

但对我来说,它需要 return some_button 而不是 break

import pyautogui
import os

def button_detector():
    path = os.path.join(ROOT_DIR, 'some_button.png')
    
    for i in range(450):
          some_button = pyautogui.locateOnScreen(path, region=(0, 510, 547, 153) , grayscale=False)
        
          if some_button is None:
              print('Button not found at trial {}'.format(i))
              print('Error: did not find any button')
          else:       
              print(some_button)
              print("Button detected")
              return some_button

# --- main ---

pos = button_detector()

if pos:
    print('button detected at position', pos)       
else:     
    print('button NOT detected')       

或者使用更少的 printssleep 因为代码可能 运行 太快了。

import pyautogui
import os
import time

def button_detector():
    path = os.path.join(ROOT_DIR, 'some_button.png')
    
    for i in range(450):
          some_button = pyautogui.locateOnScreen(path, region=(0, 510, 547, 153), grayscale=False)
        
          if some_button:
              return some_button

          #time.sleep(0.1) # to wait little longer
          
# --- main ---

pos = button_detector()

if pos:
    print('button detected at position', pos)       
else:     
    print('button NOT detected')       
    

编辑:

我检查了 locateOnScreen 的源代码,它使用了函数 pyscreeze.locateOnScreen 有选项 minSearchTime - 所以如果你想等待更长时间的按钮 - 即。 3秒后可以使用

pyautogui.locateOnScreen(..., minSearchTime=3)

它会 运行 循环,它会一次又一次地检查它 3 秒 - 你不必创建自己的循环。

import pyautogui
import os

def button_detector():
    path = os.path.join(ROOT_DIR, 'some_button.png')
    return pyautogui.locateOnScreen(path, region=(0, 510, 547, 153), 
                                    grayscale=False, minSearchTime=3)

# --- main ---

pos = button_detector()

if pos:
    print('button detected at position', pos)       
else:     
    print('button NOT detected')       

或更简单

导入pyautogui 导入 os

# --- main ---

pos = pyautogui.locateOnScreen(os.path.join(ROOT_DIR, 'some_button.png'), 
                               region=(0, 510, 547, 153), 
                               grayscale=False, 
                               minSearchTime=3)


if pos:
    print('button detected at position', pos)       
else:     
    print('button NOT detected')