From c14a7b1a67154c936086b1c3dc53562744cd17c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Melissa=20Weber=20Mendon=C3=A7a?= Date: Tue, 5 Dec 2023 10:26:36 -0300 Subject: [PATCH] Add pyautogui workflow MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Daniel Althviz Moré <16781833+dalthviz@users.noreply.github.com> --- .../generate_screenshots/coordinates.py | 11 ++ .../generate_screenshots/webm_add_points.py | 136 ++++++++++++++++++ docs/images/ok.png | Bin 0 -> 952 bytes docs/images/point-adding-tool.png | Bin 0 -> 1234 bytes docs/images/point-deleting-tool.png | Bin 0 -> 612 bytes docs/images/point-selecting-tool.png | Bin 0 -> 978 bytes requirements.txt | 1 + 7 files changed, 148 insertions(+) create mode 100644 docs/_scripts/generate_screenshots/coordinates.py create mode 100644 docs/_scripts/generate_screenshots/webm_add_points.py create mode 100644 docs/images/ok.png create mode 100644 docs/images/point-adding-tool.png create mode 100644 docs/images/point-deleting-tool.png create mode 100644 docs/images/point-selecting-tool.png diff --git a/docs/_scripts/generate_screenshots/coordinates.py b/docs/_scripts/generate_screenshots/coordinates.py new file mode 100644 index 000000000..5afe6c9ae --- /dev/null +++ b/docs/_scripts/generate_screenshots/coordinates.py @@ -0,0 +1,11 @@ +import pyautogui + +print('Press Ctrl-C to quit.') +try: + while True: + x, y = pyautogui.position() + positionStr = 'X: ' + str(x).rjust(4) + ' Y: ' + str(y).rjust(4) + print(positionStr, end='') + print('\b' * len(positionStr), end='', flush=True) +except KeyboardInterrupt: + print('\n') diff --git a/docs/_scripts/generate_screenshots/webm_add_points.py b/docs/_scripts/generate_screenshots/webm_add_points.py new file mode 100644 index 000000000..4738b43d1 --- /dev/null +++ b/docs/_scripts/generate_screenshots/webm_add_points.py @@ -0,0 +1,136 @@ +# This script generates the video for the points layer tutorial. + +# Before running, make sure to: +# 1. Install napari in development mode from the main branch +# 2. Run `napari --reset` + +# To generate the video, install pyautogui and run: +# python webm_add_points.py + +from pyautogui import click, alert, locateCenterOnScreen, moveTo, dragTo, screenshot +import numpy as np +from qtpy import QtCore +from skimage import data +from qtpy.QtWidgets import QApplication +import napari +import time + + +def apply_event(app, event, loc, msg=""): + duration = 0.3 + if event == "click_button": + button = locateCenterOnScreen(loc) + click(button, duration=duration) + if event == "click": + click(*loc, duration=duration) + if event == "move": + moveTo(*loc, duration=duration) + if event == "drag": + dragTo(*loc, button="left", duration=duration) + app.processEvents() + print(msg) + app.processEvents() + + +def run_actions(): + # Function that will be triggered from QTimer to run code even when running + # `napari.run` + print("Initial screenshot") + app = QApplication.instance() + time.sleep(1) + print("Done") + + # 1. Click add points icon + # Locate coordinates for the `Add points` buttons by using a image of the + # button + apply_event( + app, + "click_button", + "../../images/point-adding-tool.png", + msg="Click add points icon", + ) + + # 2. Add three new points + apply_event(app, "click", (700, 400), msg="Click add point 1") + apply_event(app, "click", (750, 200), msg="Click add point 2") + apply_event(app, "click", (650, 300), msg="Click add point 3") + + # 3. Click select points icon + apply_event( + app, + "click_button", + "../../images/point-selecting-tool.png", + msg="Click select points icon", + ) + + # 4. Select two points individually + apply_event(app, "click", (750, 200), msg="Click select point 1") + apply_event(app, "click", (650, 300), msg="Click select point 2") + + # 5. Drag mouse to select group of points + apply_event(app, "move", (400, 100), msg="Move to selection start") + apply_event(app, "drag", (600, 300), msg="Drag and select") + + # 6. Change face color + apply_event(app, "move", (150, 240), msg="Move to face color selection") + apply_event(app, "click", (150, 240), msg="Click face color selection") + apply_event(app, "click", (200, 240), msg="Click face color grid") + apply_event(app, "click_button", "../../images/ok.png", msg="Click OK") + + # 7. Change edge color + apply_event(app, "move", (150, 270), msg="Move to edge color selection") + apply_event(app, "click", (150, 270), msg="Click edge color selection") + apply_event(app, "click", (220, 310), msg="Click edge color grid") + apply_event(app, "click_button", "../../images/ok.png", msg="Click OK") + + # 8. Select group of points with different colors + apply_event(app, "move", (400, 200), msg="Move to selection start") + apply_event(app, "drag", (600, 400), msg="Drag and select") + + # 9. Use slider to increase point size + apply_event(app, "move", (175, 155), msg="Move to point size slider") + apply_event(app, "drag", (210, 155), msg="Drag slider") + + # 10. Select a group of points, click symbol dropdown and select cross + apply_event(app, "move", (480, 215), msg="Move to selection start") + apply_event(app, "drag", (680, 345), msg="Drag and select") + apply_event(app, "click", (295, 200), msg="Click symbol dropdown") + apply_event(app, "click", (295, 170), msg="Click cross symbol") + + # 11. Use slider to decrease and increase opacity + apply_event(app, "move", (270, 132), msg="Move to opacity slider") + apply_event(app, "drag", (180, 132), msg="Drag slider down") + apply_event(app, "drag", (270, 132), msg="Drag slider up") + + # 12. Select point and click the "delete selected points" icon + apply_event(app, "click", (440, 380), msg="Select one point") + apply_event(app, "click_button", "../../images/point-deleting-tool.png", msg="Delete point") + + # 13. Click the add points icon + apply_event(app, "click_button", "../../images/point-adding-tool.png", msg="Click add points icon") + + # 14. Use the face color dropdown to select a different color + apply_event(app, "click", (150, 240), msg="Click face color selection") + apply_event(app, "click", (310, 180), msg="Click face color grid") + apply_event(app, "click_button", "../../images/ok.png", msg="Click OK") + + # 15. Use the slider to increase point size and add new points + apply_event(app, "click", (210, 155), msg="Click point size slider") + apply_event(app, "drag", (170, 155), msg="Drag slider down") + apply_event(app, "click", (500, 500), msg="Click add point") + apply_event(app, "move", (800, 600), msg="Move mouse") + + screenshot("fallback.png") + + +viewer = napari.Viewer() +viewer.window.set_geometry(0, 0, 800, 600) +viewer.add_image(data.astronaut(), rgb=True) +points = np.array([[100, 100], [200, 200], [300, 100]]) +points_layer = viewer.add_points(points, size=30) +# Wait a bit so that the user has time to move the app to the foreground +print("Make sure the qt app is in the foreground... waiting 3s to trigger actions") +QtCore.QTimer.singleShot(3000, run_actions) + +print("Launched napari") +napari.run() diff --git a/docs/images/ok.png b/docs/images/ok.png new file mode 100644 index 0000000000000000000000000000000000000000..aa01573bddfb4b1bf9326d776319683a56446014 GIT binary patch literal 952 zcmV;p14sOcP)e}WGpN}-n*YfC|k6lW1zIG9B-`;yWL?d znp3E1n#koa(fi}mF;iv~f(QV+-GR5(HzQ_}Q3xWYF!t3XqmZ#==&)qyuw>}4Wa#+U zWN4Zo9*Y{o|0zt1uGv5ng3!ePvMl4TFEthe3gr!N(cZe6#+owRvdV+o*XaNKG(Yu? zkV#cbHwf%n3F>Z2HA!@V3m5ujxK+pI2{*-o-8 zpk+rVtFE8qi|)u|=H!7{lOaTg(C8qFqTpZNoLvMUl`h3sewU%)zYvD9hv89z!b{y^ z-@eQhPWoXMG-Wz4T$M9q?yxftjt9*+?m z8NlImP+QmZ)S;nAdvJ|QZ0Ek=s);&ydYbRUZ@KWJYkZm5S8d~^ZOEb}) zGxVEY3>vBMFC0Ci($dvNW45e%0rEDrRxVhG%jKr1xa8SI0H853c#=cub+or`=HpFe zxaBkxwS!FS$0biE(pz}ExZH#&PxB;yC+*WO&KKb`ZOJNw7< zabAYWT)~o|!;+!HlA*(rp~ECYRr9g``+s2Ut4T)Wa@bU9E;98KNsnorQOKAwqmZ#= a==d9#e-RQdY2i-*0000Xl$ETy^Dl63Of)WxF>zsBs0+j>3rSp=)B=UU7FsB6nSr4w6@~ep_Rc*nI&(Yc z(ix@+Ri0#$d*0vu_}%xs=RI@9;UlAxrvS|!_`i5+jOfZp2wMDp+#WBQwlyA2(+@HKo;aGOS2lvq56Cu#LP0{ZE{eT;bH;GNnkV>T$?Qt}0MAI}5 z9USIBbP&D#Hb$vLE}H`(@OeE1TDK8sjdCD5$YgAaU&k+Cnx^ee8`F>xm($7UTSo|W z?Ltb)%=H`mer1;1$-BsMu+zCAqG*TX9ZqU_$;!KojArcf-}?)WH}WdGg)bY18A+#+}Gs+nkn#O);WHxuZ(gQ2|xc3GjWk^bHY08>|IZA#-zU%3WA ze^0k6*r>T`G$CjUY)48-BDrM6b$$I3M^yuK=nk~1imWuZ_^l)W?d<`C5Y{TQQ`3mo z>p=)XCY!T*fzRt7(ZYj3t0BHJ7=7=}@*x)NHqKf|%3Z_=dejGw>6!p(%D!zTBd-_BoR zF>wpG%gwvTM~Rf@yh5?KLb14_#3JD!?;L*{x64U9k!1YbMMd9;x*4f3zZhpnTN^vt z13W+QEW0{(U>FAJOqNo4r8GA+(HjYK`1OMv8X2ZZ*NG>RoIZ0Fqoii5LUl$&^#|6j z&h^z{M+m{oFAgy>9HrUWY{m2CsdBrVR?ILACMGX4e(qx3m2!9Kj&)qKkJyn?GBFur z>gp_mdk5(6?WUu>-7;WG$-U+K%rC~dJUvslXKX~nMk?g;1tu=Un79x_2!Y$}LX_k6 z-u`hYMoiP()IWJCCAnPQ9&U(|t!|X3=5rfwNLxW6uTGtkkyN>gU2e}K-yKhiQmI5C wpR=A-L9G!fNu^TCr{I4@;{~zBJT*rC1#8E>G^Ou0ga7~l07*qoM6N<$f^P{`C;$Ke literal 0 HcmV?d00001 diff --git a/docs/images/point-deleting-tool.png b/docs/images/point-deleting-tool.png new file mode 100644 index 0000000000000000000000000000000000000000..ef06d9537e95a067a1083945a9581c38c17aa182 GIT binary patch literal 612 zcmV-q0-ODbP)Q+x7x%T98Y zqhgg-ZEIY(acQE7#>AMo5Xu0q%0iuIabarU&NPhE2aVy|-QT@u?w6B0xw$f1y4U3h z5mAF-bL51gY7mddNhHRJXqq~;uWY+6oz519Vf5vm4jqOJKt$6>B*xX)D|8q#JNWJ8 z5gIllp+Ss<2JwFgMKz79S1uqT>J%cv)Wx9>k-nHHIJl5%kt5kW*)n7=`GI*n~Ry!-e`EenL_E(?O*YExNRd?|cfpl^b!!&tVeSzL;Q>*JNufD`_TrOoZ z6lSigWq}AK^!dwIe*FB!qbJX4^_-z^^-Z2W+rYFeYMafTir|R)>NtL4qIb9}$6_%o z+g4)$;$veNrm4ohH1$T`I8=v#U1fm4GJb>>Iw(d$gBS@7!Xvcpx@vS_`0eEp>U6ez y7w$JZPiYm;U1k^thOxIBdoOr8G;BsfgZK^9Capz*Jj2xh0000PB)$Ds?%vp!EtaxAUGI|4Jp{Nk(^kTyD)Yv1qQ^c`Bu93T;KbR zbbO8^JpA&j2JZkK=fwYoXd4LvvLxa22k>~V$I-GZ4E+eLT!zM*hhY#>YTcA zJRVQ`3{BJC%(t%qpFhw!yjHq>e%sh4a$S$(B)nd)ZG3YlpTU_Tk)c68|Lg(%eZ9`m zm16(boWSBjoRP>dA0=kkE$p$h{Fo=t)-lbxbLpkwgMPyOcgg4X`QfKuc%I23dcA}~Dxn^gi4R7JPfgGziX0Y8 zysp)p+nk6i5r9&;!u-q>y&;vqmLE~l%B*c{vYbq#8wNe9f+9;qhVHR2ALq{P9t^`k zD<3(xvf*09Fseib!-PUAC9O^aX{4X7^Jw)cHPa;2qoODhBhg_Jv(xzf z-MrY^w&hW$$eDGd#oERul_QJnL)i{lU2%X%kg z){z#LWsyv!`Q+mSb2F3V@`ZLR7LBl&m?b>Whv+EXFaJH@#dePMjSQ8_={a+55rCCc zng@&XjE}|m^|#+Kss;dGJp2?{Zg$kx!P#t%>`o5dsCI5~Dy~Gda)oElGmOQe#3#r2 zdF3$xv++p;L11_=48V47_relz0g+60hr?nC zRgsAf4>5EsvbCLataOKKkw&AzKgm@9=4L0`cVsJj!y*8w)hC#yN$mbG%5i?=_x7F3 zTyY^0qxy>U+6ICk0L}ccEX%RV9TyS-SV}gN7A~J3a0!uoey?5BHZxgA)IF~1h?DPs z{25hIDC{?z;AOChSeE7LOO%EH#82><{907*qoM6N<$f~acN A