mirror of
https://github.com/opencv/opencv.git
synced 2025-08-06 14:36:36 +08:00
Merge pull request #19411 from crackwitz:highgui-pollkey
This commit is contained in:
commit
9d227641c9
@ -348,23 +348,34 @@ The function waitKey waits for a key event infinitely (when \f$\texttt{delay}\le
|
|||||||
milliseconds, when it is positive. Since the OS has a minimum time between switching threads, the
|
milliseconds, when it is positive. Since the OS has a minimum time between switching threads, the
|
||||||
function will not wait exactly delay ms, it will wait at least delay ms, depending on what else is
|
function will not wait exactly delay ms, it will wait at least delay ms, depending on what else is
|
||||||
running on your computer at that time. It returns the code of the pressed key or -1 if no key was
|
running on your computer at that time. It returns the code of the pressed key or -1 if no key was
|
||||||
pressed before the specified time had elapsed.
|
pressed before the specified time had elapsed. To check for a key press but not wait for it, use
|
||||||
|
#pollKey.
|
||||||
|
|
||||||
@note
|
@note The functions #waitKey and #pollKey are the only methods in HighGUI that can fetch and handle
|
||||||
|
GUI events, so one of them needs to be called periodically for normal event processing unless
|
||||||
|
HighGUI is used within an environment that takes care of event processing.
|
||||||
|
|
||||||
This function is the only method in HighGUI that can fetch and handle events, so it needs to be
|
@note The function only works if there is at least one HighGUI window created and the window is
|
||||||
called periodically for normal event processing unless HighGUI is used within an environment that
|
active. If there are several HighGUI windows, any of them can be active.
|
||||||
takes care of event processing.
|
|
||||||
|
|
||||||
@note
|
|
||||||
|
|
||||||
The function only works if there is at least one HighGUI window created and the window is active.
|
|
||||||
If there are several HighGUI windows, any of them can be active.
|
|
||||||
|
|
||||||
@param delay Delay in milliseconds. 0 is the special value that means "forever".
|
@param delay Delay in milliseconds. 0 is the special value that means "forever".
|
||||||
*/
|
*/
|
||||||
CV_EXPORTS_W int waitKey(int delay = 0);
|
CV_EXPORTS_W int waitKey(int delay = 0);
|
||||||
|
|
||||||
|
/** @brief Polls for a pressed key.
|
||||||
|
|
||||||
|
The function pollKey polls for a key event without waiting. It returns the code of the pressed key
|
||||||
|
or -1 if no key was pressed since the last invocation. To wait until a key was pressed, use #waitKey.
|
||||||
|
|
||||||
|
@note The functions #waitKey and #pollKey are the only methods in HighGUI that can fetch and handle
|
||||||
|
GUI events, so one of them needs to be called periodically for normal event processing unless
|
||||||
|
HighGUI is used within an environment that takes care of event processing.
|
||||||
|
|
||||||
|
@note The function only works if there is at least one HighGUI window created and the window is
|
||||||
|
active. If there are several HighGUI windows, any of them can be active.
|
||||||
|
*/
|
||||||
|
CV_EXPORTS_W int pollKey();
|
||||||
|
|
||||||
/** @brief Displays an image in the specified window.
|
/** @brief Displays an image in the specified window.
|
||||||
|
|
||||||
The function imshow displays an image in the specified window. If the window was created with the
|
The function imshow displays an image in the specified window. If the window was created with the
|
||||||
@ -384,11 +395,12 @@ If the window was not created before this function, it is assumed creating a win
|
|||||||
|
|
||||||
If you need to show an image that is bigger than the screen resolution, you will need to call namedWindow("", WINDOW_NORMAL) before the imshow.
|
If you need to show an image that is bigger than the screen resolution, you will need to call namedWindow("", WINDOW_NORMAL) before the imshow.
|
||||||
|
|
||||||
@note This function should be followed by cv::waitKey function which displays the image for specified
|
@note This function should be followed by a call to cv::waitKey or cv::pollKey to perform GUI
|
||||||
milliseconds. Otherwise, it won't display the image. For example, **waitKey(0)** will display the window
|
housekeeping tasks that are necessary to actually show the given image and make the window respond
|
||||||
infinitely until any keypress (it is suitable for image display). **waitKey(25)** will display a frame
|
to mouse and keyboard events. Otherwise, it won't display the image and the window might lock up.
|
||||||
for 25 ms, after which display will be automatically closed. (If you put it in a loop to read
|
For example, **waitKey(0)** will display the window infinitely until any keypress (it is suitable
|
||||||
videos, it will display the video frame-by-frame)
|
for image display). **waitKey(25)** will display a frame and wait approximately 25 ms for a key
|
||||||
|
press (suitable for displaying a video frame-by-frame). To remove the window, use cv::destroyWindow.
|
||||||
|
|
||||||
@note
|
@note
|
||||||
|
|
||||||
|
@ -297,6 +297,8 @@ int cv::waitKey(int delay)
|
|||||||
return (code != -1) ? (code & 0xff) : -1;
|
return (code != -1) ? (code & 0xff) : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: cv::pollKey has no C API equivalent. it is implemented in each backend source file.
|
||||||
|
|
||||||
int cv::createTrackbar(const String& trackbarName, const String& winName,
|
int cv::createTrackbar(const String& trackbarName, const String& winName,
|
||||||
int* value, int count, TrackbarCallback callback,
|
int* value, int count, TrackbarCallback callback,
|
||||||
void* userdata)
|
void* userdata)
|
||||||
|
@ -382,6 +382,13 @@ CV_IMPL int cvWaitKey(int delay)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int cv::pollKey()
|
||||||
|
{
|
||||||
|
CV_TRACE_FUNCTION();
|
||||||
|
// fallback. please implement a proper polling function
|
||||||
|
return cvWaitKey(1);
|
||||||
|
}
|
||||||
|
|
||||||
//Yannick Verdie
|
//Yannick Verdie
|
||||||
//This function is experimental and some functions (such as cvSet/getWindowProperty will not work)
|
//This function is experimental and some functions (such as cvSet/getWindowProperty will not work)
|
||||||
//We recommend not using this function for now
|
//We recommend not using this function for now
|
||||||
|
@ -632,6 +632,13 @@ CV_IMPL int cvWaitKey (int maxWait)
|
|||||||
return returnCode;
|
return returnCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cv::pollKey()
|
||||||
|
{
|
||||||
|
CV_TRACE_FUNCTION();
|
||||||
|
// fallback. please implement a proper polling function
|
||||||
|
return cvWaitKey(1);
|
||||||
|
}
|
||||||
|
|
||||||
CvRect cvGetWindowRect_COCOA( const char* name )
|
CvRect cvGetWindowRect_COCOA( const char* name )
|
||||||
{
|
{
|
||||||
CvRect result = cvRect(-1, -1, -1, -1);
|
CvRect result = cvRect(-1, -1, -1, -1);
|
||||||
|
@ -1950,6 +1950,13 @@ CV_IMPL int cvWaitKey( int delay )
|
|||||||
return last_key;
|
return last_key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cv::pollKey()
|
||||||
|
{
|
||||||
|
CV_TRACE_FUNCTION();
|
||||||
|
// fallback. please implement a proper polling function
|
||||||
|
return cvWaitKey(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#endif // HAVE_GTK
|
#endif // HAVE_GTK
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
|
@ -2064,6 +2064,97 @@ static void showSaveDialog(CvWindow* window)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* message received. check if it belongs to our windows (frame, hwnd).
|
||||||
|
* returns true (and value in keyCode) if a key was pressed.
|
||||||
|
* otherwise returns false (indication to continue event loop).
|
||||||
|
*/
|
||||||
|
static bool handleMessage(MSG& message, int& keyCode)
|
||||||
|
{
|
||||||
|
// whether we have to call translate and dispatch yet
|
||||||
|
// otherwise the message was handled specifically
|
||||||
|
bool is_processed = false;
|
||||||
|
|
||||||
|
for (CvWindow* window = hg_windows; window != 0 && is_processed == 0; window = window->next)
|
||||||
|
{
|
||||||
|
if (!(window->hwnd == message.hwnd || window->frame == message.hwnd))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
is_processed = true;
|
||||||
|
switch (message.message)
|
||||||
|
{
|
||||||
|
case WM_DESTROY:
|
||||||
|
case WM_CHAR:
|
||||||
|
DispatchMessage(&message);
|
||||||
|
keyCode = (int)message.wParam;
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case WM_SYSKEYDOWN:
|
||||||
|
if (message.wParam == VK_F10)
|
||||||
|
{
|
||||||
|
is_processed = true;
|
||||||
|
keyCode = (int)(message.wParam << 16);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case WM_KEYDOWN:
|
||||||
|
TranslateMessage(&message);
|
||||||
|
if ((message.wParam >= VK_F1 && message.wParam <= VK_F24) ||
|
||||||
|
message.wParam == VK_HOME || message.wParam == VK_END ||
|
||||||
|
message.wParam == VK_UP || message.wParam == VK_DOWN ||
|
||||||
|
message.wParam == VK_LEFT || message.wParam == VK_RIGHT ||
|
||||||
|
message.wParam == VK_INSERT || message.wParam == VK_DELETE ||
|
||||||
|
message.wParam == VK_PRIOR || message.wParam == VK_NEXT)
|
||||||
|
{
|
||||||
|
DispatchMessage(&message);
|
||||||
|
is_processed = true;
|
||||||
|
keyCode = (int)(message.wParam << 16);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Intercept Ctrl+C for copy to clipboard
|
||||||
|
if ('C' == message.wParam && (::GetKeyState(VK_CONTROL) >> 15))
|
||||||
|
::SendMessage(message.hwnd, WM_COPY, 0, 0);
|
||||||
|
|
||||||
|
// Intercept Ctrl+S for "save as" dialog
|
||||||
|
if ('S' == message.wParam && (::GetKeyState(VK_CONTROL) >> 15))
|
||||||
|
showSaveDialog(window);
|
||||||
|
|
||||||
|
default:
|
||||||
|
DispatchMessage(&message);
|
||||||
|
is_processed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_processed)
|
||||||
|
{
|
||||||
|
TranslateMessage(&message);
|
||||||
|
DispatchMessage(&message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false; // no value to return, keep processing
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* process until queue is empty but don't wait.
|
||||||
|
*/
|
||||||
|
int cv::pollKey()
|
||||||
|
{
|
||||||
|
CV_TRACE_FUNCTION();
|
||||||
|
for(;;)
|
||||||
|
{
|
||||||
|
MSG message;
|
||||||
|
if (PeekMessage(&message, 0, 0, 0, PM_REMOVE) == FALSE)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
int keyCode = -1;
|
||||||
|
if (handleMessage(message, keyCode))
|
||||||
|
return keyCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
CV_IMPL int
|
CV_IMPL int
|
||||||
cvWaitKey( int delay )
|
cvWaitKey( int delay )
|
||||||
{
|
{
|
||||||
@ -2072,9 +2163,7 @@ cvWaitKey( int delay )
|
|||||||
|
|
||||||
for(;;)
|
for(;;)
|
||||||
{
|
{
|
||||||
CvWindow* window;
|
|
||||||
MSG message;
|
MSG message;
|
||||||
int is_processed = 0;
|
|
||||||
|
|
||||||
if( (delay <= 0) && hg_windows)
|
if( (delay <= 0) && hg_windows)
|
||||||
GetMessage(&message, 0, 0, 0);
|
GetMessage(&message, 0, 0, 0);
|
||||||
@ -2087,61 +2176,9 @@ cvWaitKey( int delay )
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for( window = hg_windows; window != 0 && is_processed == 0; window = window->next )
|
int keyCode = -1;
|
||||||
{
|
if (handleMessage(message, keyCode))
|
||||||
if( window->hwnd == message.hwnd || window->frame == message.hwnd )
|
return keyCode;
|
||||||
{
|
|
||||||
is_processed = 1;
|
|
||||||
switch(message.message)
|
|
||||||
{
|
|
||||||
case WM_DESTROY:
|
|
||||||
case WM_CHAR:
|
|
||||||
DispatchMessage(&message);
|
|
||||||
return (int)message.wParam;
|
|
||||||
|
|
||||||
case WM_SYSKEYDOWN:
|
|
||||||
if( message.wParam == VK_F10 )
|
|
||||||
{
|
|
||||||
is_processed = 1;
|
|
||||||
return (int)(message.wParam << 16);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case WM_KEYDOWN:
|
|
||||||
TranslateMessage(&message);
|
|
||||||
if( (message.wParam >= VK_F1 && message.wParam <= VK_F24) ||
|
|
||||||
message.wParam == VK_HOME || message.wParam == VK_END ||
|
|
||||||
message.wParam == VK_UP || message.wParam == VK_DOWN ||
|
|
||||||
message.wParam == VK_LEFT || message.wParam == VK_RIGHT ||
|
|
||||||
message.wParam == VK_INSERT || message.wParam == VK_DELETE ||
|
|
||||||
message.wParam == VK_PRIOR || message.wParam == VK_NEXT )
|
|
||||||
{
|
|
||||||
DispatchMessage(&message);
|
|
||||||
is_processed = 1;
|
|
||||||
return (int)(message.wParam << 16);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Intercept Ctrl+C for copy to clipboard
|
|
||||||
if ('C' == message.wParam && (::GetKeyState(VK_CONTROL)>>15))
|
|
||||||
::SendMessage(message.hwnd, WM_COPY, 0, 0);
|
|
||||||
|
|
||||||
// Intercept Ctrl+S for "save as" dialog
|
|
||||||
if ('S' == message.wParam && (::GetKeyState(VK_CONTROL)>>15))
|
|
||||||
showSaveDialog(window);
|
|
||||||
|
|
||||||
default:
|
|
||||||
DispatchMessage(&message);
|
|
||||||
is_processed = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( !is_processed )
|
|
||||||
{
|
|
||||||
TranslateMessage(&message);
|
|
||||||
DispatchMessage(&message);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,6 +205,14 @@ CV_IMPL int cvGetTrackbarPos(const char* trackbar_name, const char* window_name)
|
|||||||
|
|
||||||
/********************************** Not YET implemented API ****************************************************/
|
/********************************** Not YET implemented API ****************************************************/
|
||||||
|
|
||||||
|
int cv::pollKey()
|
||||||
|
{
|
||||||
|
CV_TRACE_FUNCTION();
|
||||||
|
CV_WINRT_NO_GUI_ERROR("cvPollKey");
|
||||||
|
|
||||||
|
// TODO: implement appropriate logic here
|
||||||
|
}
|
||||||
|
|
||||||
CV_IMPL int cvWaitKey(int delay)
|
CV_IMPL int cvWaitKey(int delay)
|
||||||
{
|
{
|
||||||
CV_WINRT_NO_GUI_ERROR("cvWaitKey");
|
CV_WINRT_NO_GUI_ERROR("cvWaitKey");
|
||||||
|
Loading…
Reference in New Issue
Block a user