question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Use LocateOnScreen with Multiple Monitors

See original GitHub issue

I have an extra monitor plugged into my laptop many times (but not all the time) and I recently noticed that the following code:

    import pyautogui
    change_intense_to_calm = pyautogui.locateOnScreen('Intense.png', confidence = 0.9)
    run_script_button_x, run_script_button_y = pyautogui.center(change_intense_to_calm)
    pyautogui.click(run_script_button_x, run_script_button_y)

doesn’t work when the 'Intense.png" item appears on the second monitor! It does move the mouse to the position and click if it appears on the primary monitor (the laptop screen), but if the window containing that item is on the secondary monitor, it fails, giving me this error:

    Traceback (most recent call last):
      File "E:\test_folder\switch.py", line 18, in <module>
        run_script_button_x, run_script_button_y = pyautogui.center(change_intense_to_calm)
      File "C:\Program Files\Python\Python37\lib\site-packages\pyscreeze\__init__.py", line 407, in center
        return (coords[0] + int(coords[2] / 2), coords[1] + int(coords[3] / 2))
    TypeError: 'NoneType' object is not subscriptable

presumably because it’s not finding it.

How can I modify my code so that it will find the item and click it regardless of which monitor the window containing it is located on?

Issue Analytics

  • State:open
  • Created 4 years ago
  • Reactions:4
  • Comments:24

github_iconTop GitHub Comments

23reactions
Maracaipe611commented, Feb 12, 2021

Add these 3 lines to the top of your code to enable all monitor screengrabs in Windows:

from PIL import ImageGrab
from functools import partial
ImageGrab.grab = partial(ImageGrab.grab, all_screens=True)
13reactions
pascallocommented, May 17, 2020

If still relevant for someone on windows:

In my opinion the issue is, that the current version of pyscreeze utilizing ImageGrab (Pillow) on windows only uses single-screen grab.

A dirty quick fix in pyscreeze could be:

  • enable all_screen grabbing: In file: pyscreeze/__init__.py, function: def _screenshot_win32(imageFilename=None, region=None): change im = ImageGrab.grab() to im = ImageGrab.grab(all_screens= True)

  • handle new introduced negative coordinates due to multiple monitor: In file: pyscreeze/__init__.py, function: def locateOnScreen(image, minSearchTime=0, **kwargs): behind retVal = locate(image, screenshotIm, **kwargs) add

if retVal and sys.platform == 'win32':
    # get the lowest x and y coordinate of the monitor setup
    monitors = win32api.EnumDisplayMonitors()
    x_min = min([mon[2][0] for mon in monitors])
    y_min = min([mon[2][1] for mon in monitors])
    # add negative offset due to multi monitor
    retVal = Box(left=retVal[0] + x_min, top=retVal[1] + y_min, width=retVal[2], height=retVal[3])
  • don’t forget to add the import win32api In file: pyscreeze/__init__.py,:
if sys.platform == 'win32': # TODO - Pillow now supports ImageGrab on macOS.
    import win32api # used for multi-monitor fix
    from PIL import ImageGrab
Read more comments on GitHub >

github_iconTop Results From Across the Web

PyAutoGUI with multiple monitors : r/learnpython - Reddit
I wrote a gui app on a laptop and had external monitor, but using the locate centre onscreen only found the image if...
Read more >
Pyautogui in specific screen app in 2 monitors - Stack Overflow
First question, how can I make pyautogui.locateOnScreen() in a specific app window on windows? Example, search for an image only in the windows ......
Read more >
pyautogui multiple monitors
pyautogui locate on screen confidence. PyAutoGUI can take screenshots, save them to files, and locate images within the screen. This is useful if...
Read more >
Screenshot Functions - PyAutoGUI documentation
PyAutoGUI can take screenshots, save them to files, and locate images within the screen. This is useful if you have a small image...
Read more >
PyAutoGUI - Locate anything on your screen - YouTube
This is the second tutorial video on PyAutoGUI. In this tutorial I will teach you to locate anything on your screen using ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found