Skip to content
Permalink
Browse files

New class QgsFocusWatcher for easier handling of focus events

Usually QObjects must subclass and override methods like focusOutEvent
to handle focus events. Using this class as an event filter avoids
the need to subclass objects and the focus events can be directly
caught using the emitted signals.
  • Loading branch information
nyalldawson committed May 2, 2016
1 parent 6173539 commit 565488693348929e454991b876f4577b525daf81
@@ -77,6 +77,7 @@
%Include qgsfiledropedit.sip
%Include qgsfilewidget.sip
%Include qgsfilterlineedit.sip
%Include qgsfocuswatcher.sip
%Include qgsformannotationitem.sip
%Include qgsgenericprojectionselector.sip
%Include qgsgeometryrubberband.sip
@@ -0,0 +1,38 @@
/** \ingroup gui
* \class QgsFocusWatcher
* A event filter for watching for focus events on a parent object. Usually QObjects must
* subclass and override methods like focusOutEvent to handle focus events. Using this class
* as an event filter avoids the need to subclass objects and the focus events can be directly
* caught using the emitted signals.
* \note added in 2.16
*/

class QgsFocusWatcher: QObject
{
%TypeHeaderCode
#include <qgsfocuswatcher.h>
%End

public:

/** Constructor for QgsFocusWatcher.
* @param parent parent widget to catch focus events for. This class will automatically be
* installed as an event filter for parent.
*/
explicit QgsFocusWatcher( QObject* parent /TransferThis/ );

virtual bool eventFilter( QObject* obj, QEvent* event );

signals:

/** Emitted when parent object's focus changes.
* @param focused true if object gained focus, false if object lost focus
*/
void focusChanged( bool focused );

//! Emitted when parent object gains focus.
void focusIn();

//! Emitted when parent object loses focus.
void focusOut();
};
@@ -206,6 +206,7 @@ SET(QGIS_GUI_SRCS
qgsfiledropedit.cpp
qgsfilewidget.cpp
qgsfilterlineedit.cpp
qgsfocuswatcher.cpp
qgsformannotationitem.cpp
qgsgenericprojectionselector.cpp
qgsgeometryrubberband.cpp
@@ -350,6 +351,7 @@ SET(QGIS_GUI_MOC_HDRS
qgsfiledropedit.h
qgsfilewidget.h
qgsfilterlineedit.h
qgsfocuswatcher.h
qgsformannotationitem.h
qgsgenericprojectionselector.h
qgsgroupwmsdatadialog.h
@@ -0,0 +1,42 @@
/***************************************************************************
qgsfocuswatcher.h
-----------------
Date : April 2016
Copyright : (C) 2016 by Nyall Dawson
Email : nyall dot dawson at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#include "qgsfocuswatcher.h"
#include <QEvent>

QgsFocusWatcher::QgsFocusWatcher( QObject* parent )
: QObject( parent )
{
Q_ASSERT( parent );
parent->installEventFilter( this );
}

bool QgsFocusWatcher::eventFilter( QObject*, QEvent* event )
{
switch ( event->type() )
{
case QEvent::FocusIn:
emit focusChanged( true );
emit focusIn();
break;
case QEvent::FocusOut:
emit focusChanged( false );
emit focusOut();
break;
default:
break;
}
return false;
}
@@ -0,0 +1,59 @@
/***************************************************************************
qgsfocuswatcher.h
-----------------
Date : April 2016
Copyright : (C) 2016 by Nyall Dawson
Email : nyall dot dawson at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

#ifndef QGSFOCUSWATCHER_H
#define QGSFOCUSWATCHER_H

#include <QObject>

/** \ingroup gui
* \class QgsFocusWatcher
* A event filter for watching for focus events on a parent object. Usually QObjects must
* subclass and override methods like focusOutEvent to handle focus events. Using this class
* as an event filter avoids the need to subclass objects and the focus events can be directly
* caught using the emitted signals.
* \note added in 2.16
*/

class GUI_EXPORT QgsFocusWatcher : public QObject
{
Q_OBJECT

public:

/** Constructor for QgsFocusWatcher.
* @param parent parent widget to catch focus events for. This class will automatically be
* installed as an event filter for parent.
*/
explicit QgsFocusWatcher( QObject* parent );

virtual bool eventFilter( QObject* obj, QEvent* event ) override;

signals:

/** Emitted when parent object's focus changes.
* @param focused true if object gained focus, false if object lost focus
*/
void focusChanged( bool focused );

//! Emitted when parent object gains focus.
void focusIn();

//! Emitted when parent object loses focus.
void focusOut();

};

#endif //QGSFOCUSWATCHER_H
@@ -130,6 +130,7 @@ ADD_QGIS_TEST(doublespinbox testqgsdoublespinbox.cpp)
ADD_QGIS_TEST(dualviewtest testqgsdualview.cpp)
ADD_QGIS_TEST(fieldexpressionwidget testqgsfieldexpressionwidget.cpp)
ADD_QGIS_TEST(filewidget testqgsfilewidget.cpp)
ADD_QGIS_TEST(focuswatcher testqgsfocuswatcher.cpp)
ADD_QGIS_TEST(mapcanvastest testqgsmapcanvas.cpp)
ADD_QGIS_TEST(projectionissues testprojectionissues.cpp)
ADD_QGIS_TEST(qgsguitest testqgsgui.cpp)
@@ -0,0 +1,97 @@
/***************************************************************************
testqgsfocuswatcher.cpp
----------------------
Date : April 2016
Copyright : (C) 2016 Nyall Dawson
Email : nyall dot dawson at gmail dot com
***************************************************************************
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/


#include <QtTest/QtTest>

#include "qgsfocuswatcher.h"
#include <QApplication>
#include <QLineEdit>

class TestQgsFocusWatcher: public QObject
{
Q_OBJECT
private slots:
void initTestCase(); // will be called before the first testfunction is executed.
void cleanupTestCase(); // will be called after the last testfunction was executed.
void init(); // will be called before each testfunction is executed.
void cleanup(); // will be called after every testfunction.

void testSignals();

private:

};

void TestQgsFocusWatcher::initTestCase()
{
}

void TestQgsFocusWatcher::cleanupTestCase()
{
}

void TestQgsFocusWatcher::init()
{
}

void TestQgsFocusWatcher::cleanup()
{
}

void TestQgsFocusWatcher::testSignals()
{
QWidget* w = new QWidget();
QLineEdit* e1 = new QLineEdit( w );
QLineEdit* e2 = new QLineEdit( w );
QApplication::setActiveWindow( w ); //required for focus events
e1->setFocus();

QgsFocusWatcher* watcher1 = new QgsFocusWatcher( e1 );
QgsFocusWatcher* watcher2 = new QgsFocusWatcher( e2 );

QSignalSpy spyFocusIn1( watcher1, SIGNAL( focusIn() ) );
QSignalSpy spyFocusOut1( watcher1, SIGNAL( focusOut() ) );
QSignalSpy spyFocusChanged1( watcher1, SIGNAL( focusChanged( bool ) ) );
QSignalSpy spyFocusIn2( watcher2, SIGNAL( focusIn() ) );
QSignalSpy spyFocusOut2( watcher2, SIGNAL( focusOut() ) );
QSignalSpy spyFocusChanged2( watcher2, SIGNAL( focusChanged( bool ) ) );

e2->setFocus();
QCOMPARE( spyFocusIn1.count(), 0 );
QCOMPARE( spyFocusOut1.count(), 1 );
QCOMPARE( spyFocusChanged1.count(), 1 );
QCOMPARE( spyFocusChanged1.last().at( 0 ).toBool(), false );
QCOMPARE( spyFocusIn2.count(), 1 );
QCOMPARE( spyFocusOut2.count(), 0 );
QCOMPARE( spyFocusChanged2.count(), 1 );
QCOMPARE( spyFocusChanged2.last().at( 0 ).toBool(), true );

e1->setFocus();
QCOMPARE( spyFocusIn1.count(), 1 );
QCOMPARE( spyFocusOut1.count(), 1 );
QCOMPARE( spyFocusChanged1.count(), 2 );
QCOMPARE( spyFocusChanged1.last().at( 0 ).toBool(), true );
QCOMPARE( spyFocusIn2.count(), 1 );
QCOMPARE( spyFocusOut2.count(), 1 );
QCOMPARE( spyFocusChanged2.count(), 2 );
QCOMPARE( spyFocusChanged2.last().at( 0 ).toBool(), false );

delete w;
}


QTEST_MAIN( TestQgsFocusWatcher )
#include "testqgsfocuswatcher.moc"

0 comments on commit 5654886

Please sign in to comment.
You can’t perform that action at this time.