PDA

View Full Version : Keyboard Handling



ToddAtWSU
3rd July 2006, 17:01
I am working on my video player some more and want to add in keyboard handling. I want to be able to use the space bar or right arrow key to move ahead x-number of frames that are chosen by the user using a QSpinBox. I have this QSpinBox as well as a number of buttons on my interface for the mouse to use. The problem is with using these certain keys, the focus just moves around from object to object. So I had my QAxWidget call grabKeyboard( ) so I could handle for the space bar and arrow pressing. But I also want to be able to type in a number into the QSpinBox instead of using the mouse to scroll to a value. I thought about giving the QSpinBox control of the keyboard in an if-statement in my KeyPress event handler and then after capturing the input set the focus outside the QSpinBox and give the keyboard back to the QAxWidget so it could handle it like before. Unfortunately, upon giving the control back to the QSpinBox, I never enter the KeyPress event handler so I cannot give the control back to the QAxWidget. Is there anyway I can do what I am trying to do. Does this make sense to anyone? Thanks!

ToddAtWSU
3rd July 2006, 21:29
Well I think I got it working partways. Inside my player constructor I added

mySpinBox->installEventFilter( this )
and this allows me to use the right, left, and space bar like I want to. But the problem I get now is after I load my video, the up and down buttons on the QSpinBox disappear. They are there before I load in the video, but when I load the video, they disappear. Any ideas what would cause these buttons on the QSpinBox to disappear? The textbox portion of the QSpinBox is still there however and I can click just to the right of the box and the buttons still work, they just do not appear on the video player. Thanks!

high_flyer
4th July 2006, 10:03
Its very hard to say without code.
But it could be that for some reason paint events are not getting to the spin box.

gfunk
4th July 2006, 10:54
what does your event filter look like? just checking if it calls the default event handler for events it doesn't want...

ToddAtWSU
5th July 2006, 14:25
Here is my event handler. As you can see I am trying to handle a variety of things. I will include repaintWindow( ) after this code so you can see what repaintWindow is doing since it is so vital to my project. repaintWindow() is mostly DirectShow functionality with a QLabel being drawn over the video...a 5 pixel-by-5 pixel QLabel. Does it look like my eventHandler is working correctly? Thanks!


/*
* Event handler for the any widget using the installEventFilter function
*/
bool VideoViewerWindow::eventFilter( QObject *obj, QEvent *event )
{
if( obj == mpVideoPlayer )
{
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
// Mouse Button Release handlers
if( event->type() == QEvent::MouseButtonPress )
{
AzElPoint point;
int azElSize = azElPoints.size( );
point.frameNumber = getCurrentFrame( );
point.xPos = mouseEvent->x( );
point.yPos = mouseEvent->y( );

if( mouseEvent->button() == Qt::LeftButton )
{
// If left button, place mark on overlay to indicate position
// and store position in array at the current frame index
for( int i = 0 ; i < azElSize ; i++ )
{
if( azElPoints[i].frameNumber == point.frameNumber )
{
azElPoints.removeAt( i );
erasePoint = true;
break;
}
}
azElPoints.push_back( point );
return true;
}
}
if( event->type() == QEvent::MouseButtonRelease )
{
if( mouseEvent->button() == Qt::RightButton )
{
// If right button, remove any point located in current frame
AzElPoint point;
point.frameNumber = getCurrentFrame( );
point.xPos = mouseEvent->x( );
point.yPos = mouseEvent->y( );
for( int i = 0 ; i < azElPoints.size( ) ; i++ )
{
if( azElPoints[i].frameNumber == getCurrentFrame( ) &&
( azElPoints[i].xPos >= point.xPos - 2 && azElPoints[i].xPos <= point.xPos + 2 ) &&
( azElPoints[i].yPos >= point.yPos - 2 && azElPoints[i].yPos <= point.yPos + 2 ) )
{
azElPoints.removeAt( i );
break;
}
}
update( );
return true;
}
}
}
if( event->type( ) == QEvent::Move )
{
if( pMediaSeeking != NULL )
{
repaintWindow( );
return true;
}
}
if( event->type( ) == QEvent::Paint )
{
if( pMediaSeeking != NULL )
{
repaintWindow( );
return true;
}
}
if( event->type( ) == QEvent::KeyPress )
{
if( pMediaSeeking!= NULL )
{
QKeyEvent *pressedKey = (QKeyEvent*) event;
int key = pressedKey->key( );
switch( key )
{
case Qt::Key_Space:
pressedKey->accept( );
skipAheadPressed( );
return true;
break;
case Qt::Key_Right:
pressedKey->accept( );
skipAheadPressed( );
return true;
break;
case Qt::Key_Left:
pressedKey->accept( );
skipBackPressed( );
return true;
break;
case Qt::Key_P:
pressedKey->accept( );
pausePressed( );
return true;
break;
case Qt::Key_S:
pressedKey->accept( );
stopPressed( );
return true;
break;
case Qt::Key_Home:
pressedKey->accept( );
jumpToStartPressed( );
return true;
break;
case Qt::Key_End:
pressedKey->accept( );
jumpToEndPressed( );
return true;
break;
default:
pressedKey->ignore( );
}
}
}
return QObject::eventFilter( obj, event );
}


/*
*
* repaintWindow( )
*
* This function repaints the video in its video frame so that the video will be
* upon loading and flipping back and forth between open windows.
*
*/
void VideoViewerWindow::repaintWindow( )
{
long lWidth, lHeight;
HRESULT hr = pWindowlessControl->GetNativeVideoSize( &lWidth, &lHeight, NULL, NULL );
RECT rcSrc, rcDest;
// Set the source rectangle.
SetRect( &rcSrc, 0, 0, lWidth, lHeight );

// Get the window client area.
GetClientRect( (HWND) mpVideoPlayer->winId( ), &rcDest );
// Set the destination rectangle.
SetRect(&rcDest, 1, 1, 558, 349);

// Set the video position.
hr = pWindowlessControl->SetVideoPosition( &rcSrc, &rcDest );

PAINTSTRUCT ps;
HDC hdc;
RECT rcClient;
GetClientRect( (HWND) mpVideoPlayer->winId( ), &rcClient );
hdc = BeginPaint( (HWND) mpVideoPlayer->winId( ), &ps );
if( pWindowlessControl != NULL )
{
// Find the region where the application can paint by subtracting
// the video destination rectangle from the client area.
// (Assume that g_rcDest was calculated previously.)
HRGN rgnClient = CreateRectRgnIndirect( &rcClient );
HRGN rgnVideo = CreateRectRgnIndirect( &rcDest );
CombineRgn( rgnClient, rgnClient, rgnVideo, RGN_DIFF );

// Paint on window.
HBRUSH hbr = GetSysColorBrush( COLOR_BTNFACE );
FillRgn( hdc, rgnClient, hbr );

// Clean up.
DeleteObject( hbr );
DeleteObject( rgnClient );
DeleteObject( rgnVideo );

int azElSize = azElPoints.size( );
int currentFrame = getCurrentFrame( );

// Request the VMR to paint the video and draw the point chosen by the user.
int i;
for( i = 0 ; i < azElSize ; i++ )
{
if( azElPoints[i].frameNumber == currentFrame )
{
mpOverlayLabel->move( azElPoints[i].xPos - 2, azElPoints[i].yPos - 2 );
mpOverlayLabel->show( );
break;
}
}
if( i == azElPoints.size( ) )
{
mpOverlayLabel->hide( );
}
HRESULT hr = pWindowlessControl->RepaintVideo( (HWND) mpVideoPlayer->winId( ), hdc );
}
}