Introduce QgsScreenHelper

A utility class for dyanmic handling of changes to screen properties
This commit is contained in:
Nyall Dawson 2022-08-15 13:03:31 +10:00
parent d717938b27
commit 22edb68eac
5 changed files with 253 additions and 0 deletions

View File

@ -0,0 +1,69 @@
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/qgsscreenhelper.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/
class QgsScreenHelper : QObject
{
%Docstring(signature="appended")
A utility class for dynamic handling of changes to screen properties.
.. versionadded:: 3.28
%End
%TypeHeaderCode
#include "qgsscreenhelper.h"
%End
public:
QgsScreenHelper( QWidget *parent /TransferThis/ );
%Docstring
Constructor for QgsScreenHelper for the specified parent ``widget``.
%End
QScreen *screen();
%Docstring
Returns the screen that the parent widget appears on, or ``None``.
%End
QWindow *windowHandle();
%Docstring
Returns the window handle for the window the parent widget is associated with, or ``None``.
%End
double screenDpi() const;
%Docstring
Returns the current screen DPI for the screen that the parent widget appears on.
.. seealso:: :py:func:`screenDpiChanged`
%End
signals:
void screenDpiChanged( double dpi );
%Docstring
Emitted whenever the screen ``dpi`` associated with the widget is changed.
.. seealso:: :py:func:`screenDpi`
%End
protected:
virtual bool eventFilter( QObject *watched, QEvent *event );
};
/************************************************************************
* This file has been generated automatically from *
* *
* src/gui/qgsscreenhelper.h *
* *
* Do not edit manually ! Edit header and run scripts/sipify.pl again *
************************************************************************/

View File

@ -196,6 +196,7 @@
%Include auto_generated/qgsscalerangewidget.sip
%Include auto_generated/qgsscalevisibilitydialog.sip
%Include auto_generated/qgsscalewidget.sip
%Include auto_generated/qgsscreenhelper.sip
%Include auto_generated/qgsscrollarea.sip
%Include auto_generated/qgssearchquerybuilder.sip
%Include auto_generated/qgssubsetstringeditorinterface.sip

View File

@ -629,6 +629,7 @@ set(QGIS_GUI_SRCS
qgsscalerangewidget.cpp
qgsscalevisibilitydialog.cpp
qgsscalewidget.cpp
qgsscreenhelper.cpp
qgsscrollarea.cpp
qgssearchquerybuilder.cpp
qgssubsetstringeditorinterface.cpp
@ -892,6 +893,7 @@ set(QGIS_GUI_HDRS
qgsscalerangewidget.h
qgsscalevisibilitydialog.h
qgsscalewidget.h
qgsscreenhelper.h
qgsscrollarea.h
qgssearchquerybuilder.h
qgssubsetstringeditorinterface.h

View File

@ -0,0 +1,93 @@
/***************************************************************************
qgsscreenhelper.cpp
---------------
Date : August 2022
Copyright : (C) 2022 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 "qgsscreenhelper.h"
#include "qgis.h"
#include <QWidget>
#include <QEvent>
#include <QWindow>
#include <QScreen>
QgsScreenHelper::QgsScreenHelper( QWidget *parent )
: QObject( parent )
, mWidget( parent )
{
mWidget->installEventFilter( this );
}
QScreen *QgsScreenHelper::screen()
{
if ( QWindow *windowHandle = QgsScreenHelper::windowHandle() )
{
return windowHandle->screen();
}
return nullptr;
}
QWindow *QgsScreenHelper::windowHandle()
{
if ( QWidget *window = mWidget->window() )
return window->windowHandle();
return nullptr;
}
bool QgsScreenHelper::eventFilter( QObject *watched, QEvent *event )
{
if ( watched != mWidget )
return false;
switch ( event->type() )
{
case QEvent::Show:
{
updateDevicePixelFromScreen();
// keep device pixel ratio up to date on screen or resolution change
if ( QWindow *handle = windowHandle() )
{
connect( handle, &QWindow::screenChanged, this, [ = ]( QScreen * )
{
disconnect( mScreenDpiChangedConnection );
if ( QWindow *windowHandleInLambda = windowHandle() )
{
mScreenDpiChangedConnection = connect( windowHandleInLambda->screen(), &QScreen::physicalDotsPerInchChanged, this, &QgsScreenHelper::updateDevicePixelFromScreen );
updateDevicePixelFromScreen();
}
} );
mScreenDpiChangedConnection = connect( handle->screen(), &QScreen::physicalDotsPerInchChanged, this, &QgsScreenHelper::updateDevicePixelFromScreen );
}
}
default:
break;
}
return false;
}
void QgsScreenHelper::updateDevicePixelFromScreen()
{
if ( QScreen *screen = QgsScreenHelper::screen() )
{
const double newDpi = screen->physicalDotsPerInch();
if ( !qgsDoubleNear( newDpi, mScreenDpi ) )
{
mScreenDpi = newDpi;
emit screenDpiChanged( mScreenDpi );
}
}
}

88
src/gui/qgsscreenhelper.h Normal file
View File

@ -0,0 +1,88 @@
/***************************************************************************
qgsscreenhelper.h
---------------
Date : August 2022
Copyright : (C) 2022 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 QGSSCREENHELPER_H
#define QGSSCREENHELPER_H
#include "qgis_gui.h"
#include "qgis_sip.h"
#include <QObject>
class QWidget;
class QScreen;
class QWindow;
/**
* \ingroup gui
* \class QgsScreenHelper
* \brief A utility class for dynamic handling of changes to screen properties.
*
* \since QGIS 3.28
*/
class GUI_EXPORT QgsScreenHelper : public QObject
{
Q_OBJECT
public:
/**
* Constructor for QgsScreenHelper for the specified parent \a widget.
*/
QgsScreenHelper( QWidget *parent SIP_TRANSFERTHIS );
/**
* Returns the screen that the parent widget appears on, or NULLPTR.
*/
QScreen *screen();
/**
* Returns the window handle for the window the parent widget is associated with, or NULLPTR.
*/
QWindow *windowHandle();
/**
* Returns the current screen DPI for the screen that the parent widget appears on.
*
* \see screenDpiChanged()
*/
double screenDpi() const { return mScreenDpi; }
signals:
/**
* Emitted whenever the screen \a dpi associated with the widget is changed.
*
* \see screenDpi()
*/
void screenDpiChanged( double dpi );
protected:
bool eventFilter( QObject *watched, QEvent *event ) override;
private slots:
void updateDevicePixelFromScreen();
private:
QWidget *mWidget = nullptr;
double mScreenDpi = 96.0;
QMetaObject::Connection mScreenDpiChangedConnection;
};
#endif // QGSSCREENHELPER_H