'OpenCV closing a window with a mouse click on a Raspberry Pi
What I want to do is, I want to have have a user click the close "X" button in an OpenCV window and have the program recognize it, and close that window.
It seems that this is not easy, and after four days of going round in circles and finding out how it can be done on a windows machine I am no closer to finding out how to do it on a Raspberry Pi using Python.
I think I need to get the handle of the OpenCV window ( how? ) and then use that to see if the window is still visible ( what call? ) and if it is not, bring proceedings to a halt ( I can do that bit ).
I have tried cvGetWindowHandle("window_name") but I've downloaded the source and GetWindowHandle doesn't seem to be available from python.
Solution 1:[1]
The code to capture the left button mouse click event and close a window is fairly simple:
if event == cv2.EVENT_LBUTTONDOWN:
cv2.destroyWindow("window_name")
There is a tutorial on how to use the button click event here which is where I took that code, it provides a full working example in python.
However you are probably running a unix based system on your Rpi and will therefore want to read This answer as you made need a combination of waitKey(1) in order for it to work.
Solution 2:[2]
I maybe have a solution but I'm not 100% sure so you'll have to check it yourself:) I assume the OpenCV uses X11 underneath (if no none of this makes sense). With X11 you can:
1) Find X11 window handle for your OpenCV window as described here
2) Use XSelectInput to hook into its event loop somewhat similar to what was done here. I assume you should useStructureNotifyMask as the mask to get the XDestroyWindowEvent event. Run the X11 event loop and as soon as you get the corresponding event you can call the OpenCV destroyWindow function.
This suggestion is based on assumptions and I can't give any guarantees it will work, but as far as I understand if OpenCV isn't built with some other specific window manager this should work. As far as I understand Raspbian was shipped with X11 up to some point and then it switched to Wayland. In case you have an image with Wayland then this probably will not work (and I'm sorry but my Linux skills do not contain a recipe on how to determine which one is used:D).
UPDATE
Actually after more reading I seem to feel that gtkshould be able to handle whatever is being used underneath (X11/Wayland). So if you install gtk development libraries you should also be able to connect to the windows deletion signal like described here. The only question then remains on how to obtain the window handle.
My personal advice - use Qt or some other GUI friendly framework to render the OpenCV images instead of doing it directly with OpenCV. OpenCV is an imaging framework but IMHO highgui is too unusable for anything serious.
Solution 3:[3]
all I want to do is to have a user click the close X in an openCV window
This is how I did it, in a capture loop (RPi stretch, opencv 4.0):
while True:
# do your video capture
# ...
cv.imshow("video frame",frame)
if cv.getWindowProperty('video frame', 1) < 0:
break
getWindowProperty isn't much documented but what it does is, as its name implies, to return the property of a given window. Two of the flags of interest are WND_PROP_FULLSCREEN (or 0) and WND_PROP_AUTOSIZE (or 1). When the window is closed the function returns -1. Use this to immediately break your loop (or close your window if not in a loop).
References:
Solution 4:[4]
Poll with cv2.getWindowImageRect(windowName). It will return (-1, -1, -1, -1) when the user clicks the window close button.
# check if window was closed or image was resized
xPos, yPos, width, height = cv2.getWindowImageRect(windowName)
if xPos == -1: # if user closed window
pass # do whatever you want here if the user clicked CLOSE
I haven't found this documented anywhere; discovered it by accident while handling window resizing. (Tested with OpenCV 4.1.0.)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Community |
| Solution 2 | Community |
| Solution 3 | calocedrus |
| Solution 4 |
