Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Autogenerate images of parts of the viewer #621

Open
wants to merge 18 commits into
base: main
Choose a base branch
from

Conversation

TimMonko
Copy link
Contributor

@TimMonko TimMonko commented Mar 13, 2025

References and relevant issues

Description

This is really a draft of trying to autogenerate images that we can use throughout the docs. I think this would also speed up doc generation in certain areas with reusable doc images, so that nbscreenshot would not need to be as frequent. Everything is getting saved into images/_autogenerated and could be used elsewhere.

  1. Tries to autogenerate grabbing and saving many parts of the viewer using the attributes of the viewer

Needs:

  1. Popups are not working right, sometimes they trigger, often its the dims slider popup. I probably need to just directly call the button, but I'm having a tough time figuring out where the buttons live.
  2. I think the timing of things has me really confused. I think QTimer is necessary to wait for things to popup, but I can't figure out why these popups aren't working
  3. Also sometimes the console popups and saves as a screenshot, other times its just the thin dock area prior to the console popup.

Examples of what should appear in autogenerated if CI does it the same was as locally
image

@github-actions github-actions bot added the documentation Improvements or additions to documentation label Mar 13, 2025
@TimMonko
Copy link
Contributor Author

Adding a few links from the community meeting today:
https://simonwillison.net/2022/Oct/14/automating-screenshots/
https://simonwillison.net/2022/Mar/10/shot-scraper/
napari/napari#7678
and look into qt_bot wait

@melissawm
Copy link
Member

Hi @TimMonko - this is the PR I mentioned on zulip: #308

That one is more focused on videos, so might not be helpful but just in case here it is. Cheers!

Comment on lines 42 to 50
QTimer.singleShot(100, lambda: trigger_popup(
viewer_buttons.ndisplayButton,
"ndisplay_popup",
lambda: trigger_popup(
viewer_buttons.gridViewButton,
"grid_popup",
lambda: cleanup(viewer)
)
))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not a good solution. We need to find a way to define a list of popups to iterate over it.
Maybe global list and just pass the index?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you look strictly at autogenerate-gui? I've put the most recent popup stuff in there. It's flaky, where sometimes it works and sometimes it doesn't, I've tried to include closing popups there, but yes, trying to work towards creating a list. Sorry I didn't remove this file 😬

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in 2-3 hours

Copy link
Contributor Author

@TimMonko TimMonko Mar 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

of course! no issue, I'm actually going to plug along on it for about another hour, so you should receive a better file by then

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

your review did at least confirm some of the direction I thought it needed to go

Comment on lines 66 to 68
for widget in QApplication.topLevelWidgets():
if isinstance(widget, QtPopup):
popup = widget
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The previous popup is not closed before your code triggers creation of the next popup, so the first popup is captured again. We either need to use proper class in place of QtPopup or use objectName() method (with earlier setting it).

@TimMonko TimMonko marked this pull request as ready for review March 14, 2025 16:56
@TimMonko
Copy link
Contributor Author

TimMonko commented Mar 14, 2025

@Czaki
Everything is organized in one file now, and the script is not flaky anymore.
QTimer actually seems to create more problems than fewer problems for popups, compared to menus. Perhaps I was implementing incorrectly --though I was using same logic as menus, it would be delayed asynchronously. Strangely, lowering Qtimer for capturing menus to 50ms resulting in incomplete generation of popups. The async part of this is so confusing.

  1. Creates images of many widgets
  2. Creates images of many menu items
  3. Creates images of popups with prep triggers.

We can add / change more and modify callbacks in various ways, but as @willingc we can start with a merged script and go from there.

I hope it's not flaky on anyone else's machine, or CI.

Copy link
Contributor

@willingc willingc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's merge this as is. I would like to do a pass over the script and change some of the print statements to logging (it will benefit us when running in CI).

@TimMonko
Copy link
Contributor Author

TimMonko commented Mar 15, 2025

Sounds good, the prints were really just for debugging lol. I take them out as things start to work. Definitely anything with prints from me is a 'draft'. Can still merge though if you like

We should be able to see if CI autogenerates correctly

@willingc
Copy link
Contributor

I would like us to merge and iterate on it.

@melissawm
Copy link
Member

Can we add a comment in the script to indicate which images it is generating?

@TimMonko
Copy link
Contributor Author

@melissawm I added much more commenting to try to clarify what is being saved and I hope the code organization is sufficient to be self explanatory. However, if what you mean is to specifically say which images for the docs this is generating, I'm not sure that's a good idea (will be hard to maintain and keep up to date). Please let me know if I haven't accomplished the goal.

I've also added various interactions with the canvas to change the display of various widgets -- we can always be very specific if we have things in mind to demonstrate. At this point, I'm very happy with this implementation, and want us to merge this to check it works on CI, and then we can look to specifically define images of interest that can be used in the docs.

I also added a preliminary, rough implementation of capturing regions of the viewer as defined by the widgets. In the long run, this will be more maintainable than defining the region with our own coordinates (since inevitably these coordinates could move around). Currently, it just crops to the bounds of the defined widgets, for example:

Viewer buttons + Console:
console_and_buttons

Layer list and layer controls
layer_list_and_controls

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants