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.
This commit is contained in:
Nyall Dawson 2016-05-02 16:13:35 +10:00
parent 61735390d7
commit 5654886933
7 changed files with 240 additions and 0 deletions

View File

@ -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

View File

@ -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();
};

View File

@ -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

View File

@ -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;
}

59
src/gui/qgsfocuswatcher.h Normal file
View File

@ -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

View File

@ -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)

View File

@ -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"