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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 15:51:46  来源:igfitidea点击:

OpenCV Python: How to detect if a window is closed?

pythonopencv

提问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:

那么它有什么作用:

  1. Opens a window
  2. In a loop, shows an image on the window
  3. Once finished, closes the window
  4. Runs the rest of the code
  1. 打开一个窗口
  2. 在循环中,在窗口上显示图像
  3. 完成后,关闭窗口
  4. 运行其余代码

However in this case I have the total_framegiven before. I don't want that.

但是在这种情况下,我total_frame之前已经给出了。我不想要那个。

Instead, I want a code that does the following:

相反,我想要一个执行以下操作的代码:

  1. Opens a window
  2. In a loop, shows an image on the window
  3. Waits for the user to close that window
  4. When the user closes that window, exit loop, goes on with the rest of the code.
  1. 打开一个窗口
  2. 在循环中,在窗口上显示图像
  3. 等待用户关闭该窗口
  4. 当用户关闭该窗口时,退出循环继续执行其余代码。

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 Xbutton of the window in addition to waiting for a key press, but I couldn't find an answer anywhere (IsWindowVisibleand cvGetWindowHandleare not available in the Python cv2module).

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 -1as 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 0is the fullscreen property, but actually it doesn't matter which flag to use, they all become -1as 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 waitKeyand 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;
}