Screen
Un moniteur physique. Screen(0) est l’écran principal, Screen(1), Screen(2), etc. couvrent les écrans suivants. Hérite de Region.
C’est le moteur d’OculiX. Vous lui montrez une petite image, il vous indique où elle se trouve à l’écran. Cliquer, taper, attendre — tout part de là.
Screen
Un moniteur physique. Screen(0) est l’écran principal, Screen(1), Screen(2), etc. couvrent les écrans suivants. Hérite de Region.
Region
Une zone rectangulaire dans laquelle on cherche. find, click et type opèrent dessus. Un Screen est une Region qui couvre tout l’écran.
Pattern
Une image, plus deux réglages : son seuil similar() et son targetOffset().
Match
Une recherche qui a réussi. C’est une Region, à laquelle s’ajoutent un score et le Pattern qui l’a produite.
Location
Un point (x, y). Rien de plus.
Partout où OculiX attend une image, vous pouvez passer un Pattern à la place — et inversement.
Toute opération visuelle se ramène à l’un de ces cinq appels. Chacun accepte un chemin ("button.png"), un Pattern, ou une autre Region.
find(image) — localiser une fois, planter si rienCherche l’image dans la region, renvoie un Match à la première occurrence trouvée. Lève FindFailed si rien n’est trouvé. À utiliser quand l’image doit être là.
btn = find("save.png")btn.click()exists(image) — localiser une fois, renvoyer None si rienMême chose que find(), mais retourne None à la place de lever une exception. Parfait pour les branchements conditionnels.
if exists("error_dialog.png"): click("ok_button.png")else: click("submit.png")wait(image, secs) — attendre qu’une image apparaisseBoucle jusqu’à ce que l’image apparaisse, ou jusqu’à expiration du délai. Indispensable pour synchroniser un script avec une UI qui met du temps à charger.
# Lance l'export, attend que la fenêtre de sauvegarde s'ouvre (max 10 s)click("export.png")wait("save_dialog.png", 10)type("filename_field.png", "rapport.csv")waitVanish(image, secs) — attendre qu’une image disparaisseSymétrique de wait(). Indispensable pour attendre la fin d’un chargement, d’une animation, d’un toast de confirmation. Souvent la primitive qui change tout sur une UI moderne.
# Soumet le formulaire, attend que le spinner disparaisse, puis continueclick("submit.png")waitVanish("loading_spinner.png", 30)click("next_step.png")findAll(image) — toutes les occurrencesRenvoie un itérateur sur tous les Match, triés par similarité décroissante. À utiliser dès qu’il y a plusieurs cibles identiques à traiter.
# Coche toutes les cases visibles d'un formulairefor cb in findAll("checkbox_unchecked.png"): cb.click()from sikuli import *
s = Screen(0) # moniteur principal
# Patiente jusqu'à 10 s pour que l'application s'ouvreapp = s.wait("main_window.png", 10)
# On limite la recherche au volet de droite — plus rapide, moins ambiguright_pane = app.right(app.getW() // 2)save = right_pane.find("save_button.png")
save.highlight(1.5) # visualise le match 1,5 s avant de cliquersave.click()Par défaut, OculiX exige 70 % de similarité. Vous pouvez l’ajuster pour un appel ou pour tout le script :
click(Pattern("button.png").similar(0.85)) # juste cet appelSettings.MinSimilarity = 0.65 # le script entierUn seuil haut est plus strict, un seuil bas plus permissif. L’antialiasing, la transparence, un changement de thème ou le hinting des polices abaissent tous le score. Plutôt que de recapturer l’image à chaque variation, abaissez le seuil.
Un clic OculiX tombe au centre du match. Si ce n’est pas ce que vous voulez, le targetOffset décale le point de clic :
# Clique 30 pixels à droite et 5 pixels sous le centre de l'icôneicon = Pattern("icon.png").targetOffset(30, 5)click(icon)C’est la méthode habituelle pour cliquer sur un libellé situé à côté d’une icône reconnaissable.
r = Screen(0)
r.left(200) # bande de 200 px à gaucher.right(200) # bande de 200 px à droiter.above(100) # bande de 100 px au-dessusr.below(100) # bande de 100 px en-dessousr.inside() # la region elle-mêmer.nearby(50) # élargit de 50 px tout autourr.grow(50, 100) # élargit en largeur et hauteur séparémentr.morphTo(otherRegion)Associées à find(), ces opérations rendent un script beaucoup plus stable :
# Ne cherche que dans la boîte de dialoguedialog = wait("save_dialog_title.png", 5)dialog.click("save_button.png")header = find("header_logo.png")search_box = header.right(800).below(0)search_box.click()search_box.type("oculix")Quand la mise en page bouge mais que la position relative reste stable, les ancres permettent au script de continuer à fonctionner sans repasser sur chaque image.
for m in findAll("checkbox_unchecked.png"): m.click()Vous récupérez un itérateur de Match, trié par similarité décroissante.
match = find("save_button.png")match.highlight(2)match.highlight(2, "green")Quand un script clique au mauvais endroit, c’est l’outil de diagnostic le plus rapide : highlight() montre exactement ce qu’OculiX a trouvé. La moitié des questions « pourquoi a-t-il cliqué là ? » disparaissent en quelques secondes après un coup de highlight.
Dans l’IDE, Run → Run Slow Motion ajoute une mise en évidence brève avant chaque action. Pratique pour démontrer un script à un non-technicien ou enregistrer une vidéo.
Settings.MinSimilarity = 0.7 # seuil minimum par défautSettings.AlwaysResize = 1.0 # mise à l'échelle des captures avant matchingSettings.MoveMouseDelay = 0.3 # durée du déplacement du curseur (secondes)Settings.WaitScanRate = 3 # scans par seconde pendant wait()Settings.AutoWaitTimeout = 3.0 # attente implicite avant chaque actionPlus le pattern est petit, plus le matching est rapide
Capturez serré autour de la cible. OpenCV a moins de pixels à comparer.
Limitez la zone de recherche
Une Region ciblée est toujours préférable à un balayage complet de l’écran.
Gardez les Match
Quand la mise en page ne bouge pas, target.click() est gratuit là où un nouveau find() coûte du CPU.
exists() au lieu de try/except
find() lève FindFailed si rien n’est trouvé. exists() renvoie None à la place — plus pratique pour brancher proprement, sans cascade d’exceptions à attraper.
| Erreur | Cause habituelle |
|---|---|
FindFailed | L’image n’est pas visible, elle est masquée, ou le seuil est trop strict |
ImageMissing | Le chemin est faux, ou l’image manque dans le bundle .sikuli |
org.opencv.core… | Apertix mal résolu — voir Installation |