OpenCV Python:如何检测窗口是否关闭?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/35003476/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
OpenCV Python: How to detect if a window is closed?
提问by dessskris
I have the following code:
我有以下代码:
total_frames = 50
cv2.cv.NamedWindow("Dragonfly Simulation")
cv2.cv.StartWindowThread()
for i in range(total_frames):
# do stuff
img_name = # something
img = cv2.cv.LoadImage(img_name)
cv2.cv.ShowImage("Dragonfly Simulation", img)
cv2.cv.WaitKey(2)
cv2.cv.DestroyWindow("Dragonfly Simulation")
cv2.cv.WaitKey(1)
# rest of code
So what does it do:
那么它有什么作用:
- Opens a window
- In a loop, shows an image on the window
- Once finished, closes the window
- Runs the rest of the code
- 打开一个窗口
- 在循环中,在窗口上显示图像
- 完成后,关闭窗口
- 运行其余代码
However in this case I have the total_frame
given before. I don't want that.
但是在这种情况下,我total_frame
之前已经给出了。我不想要那个。
Instead, I want a code that does the following:
相反,我想要一个执行以下操作的代码:
- Opens a window
- In a loop, shows an image on the window
- Waits for the user to close that window
- When the user closes that window, exit loop, goes on with the rest of the code.
- 打开一个窗口
- 在循环中,在窗口上显示图像
- 等待用户关闭该窗口
- 当用户关闭该窗口时,退出循环继续执行其余代码。
However, I cannot find a function in OpenCV that can detect when user closes a window. Can anyone suggest a workaround please?
但是,我在 OpenCV 中找不到可以检测用户何时关闭窗口的函数。任何人都可以提出解决方法吗?
采纳答案by Simon H?nisch
I was just looking for a way to detect when the window has been closed using the X
button of the window in addition to waiting for a key press, but I couldn't find an answer anywhere (IsWindowVisible
and cvGetWindowHandle
are not available in the Python cv2
module).
X
除了等待按键之外,我只是在寻找一种方法来检测窗口何时关闭,使用窗口的按钮,但我在任何地方都找不到答案(IsWindowVisible
并且cvGetWindowHandle
在 Pythoncv2
模块中不可用)。
So I played around and this is how it works:
所以我玩了一下,这就是它的工作原理:
while cv2.getWindowProperty('window-name', 0) >= 0:
keyCode = cv2.waitKey(50)
# ...
cv2.getWindowProperty()
returns -1
as soon as the window is closed.
cv2.getWindowProperty()
-1
关闭窗口后立即返回。
For explanation, see the documentation for the enumeration of cv::WindowPropertyFlags
: getting the flag with index 0
is the fullscreen property, but actually it doesn't matter which flag to use, they all become -1
as soon as the window is closed.
有关解释,请参阅以下枚举的文档cv::WindowPropertyFlags
:获取带有索引的标志0
是全屏属性,但实际上使用哪个标志并不重要,-1
一旦窗口关闭,它们都会变成。
回答by otterb
import cv2
import numpy as np
# total_frames = 50
cv2.namedWindow("Dragonfly Simulation")
cv2.startWindowThread()
# for i in range(total_frames):
while True:
# do stuff
img = np.random.randint(0,255,(200,300)).astype(np.uint8)
cv2.imshow("Dragonfly Simulation", img)
key = cv2.waitKey(200)
print key
if key in [ord('a'), 1048673]:
print 'a pressed!'
elif key in [27, 1048603]: # ESC key to abort, close window
cv2.destroyAllWindows()
break
# do the rest of processing after break
print 'results:'
Sure, you can check user inputs using waitKey
and here is a small example based on your code. I changed old cv interface to cv2. I think cv is obsolete.
当然,您可以使用以下方法检查用户输入waitKey
,这是一个基于您的代码的小示例。我将旧的 cv 界面更改为 cv2。我认为 cv 已经过时了。
(Edit) I moved cv2.destroyAllWindows() to inside the while loop to make it clear that the window closes when the user pressed ESC key (which you can assign a key of your choice). I do not think opencv has a proper event handler to catch the window close event like in other GUI toolkit (wxPython etc). So you will need to define how your users should close the window and watch out for that.
(编辑)我将 cv2.destroyAllWindows() 移动到 while 循环内部,以明确当用户按下 ESC 键(您可以指定一个您选择的键)时窗口关闭。我认为 opencv 没有合适的事件处理程序来像其他 GUI 工具包(wxPython 等)中那样捕获窗口关闭事件。所以你需要定义你的用户应该如何关闭窗口并注意这一点。
回答by David Kohen
As of version 2.2 there is a simple solution (this is modified from the loop in hist.py):
从 2.2 版开始,有一个简单的解决方案(这是从 hist.py 中的循环修改的):
cv2.imshow('image',im)
while True:
k = cv2.waitKey(100) # change the value from the original 0 (wait forever) to something appropriate
...
elif k == 27:
print('ESC')
cv2.destroyAllWindows()
break
if cv2.getWindowProperty('image',cv2.WND_PROP_VISIBLE) < 1:
break
cv2.destroyAllWindows()
回答by stephen george
if cv2.getWindowProperty('windowname',1) == -1 :
break
cv2.imshow('windowname', image)
回答by Derzu
I tested on C++ using the getWindowProperty('image', WND_PROP_VISIBLE), but it does not work. So I used the WND_PROP_AUTOSIZE and it works.
我使用 getWindowProperty('image', WND_PROP_VISIBLE) 在 C++ 上进行了测试,但它不起作用。所以我使用了 WND_PROP_AUTOSIZE 并且它有效。
I did like this:
我是这样的:
cv::namedWindow("myTitle", WINDOW_AUTOSIZE);
while(1)
{
cv::imshow("myTitle", myImage);
if (cv::getWindowProperty("myTitle", WND_PROP_AUTOSIZE) == -1)
break;
}