[Interest] How to be notified when widget is moved to another screen?

Adam Light aclight at gmail.com
Fri Oct 21 14:57:54 CEST 2016


On Fri, Oct 21, 2016 at 12:47 AM, Elvis Stansvik <elvstone at gmail.com> wrote:

> 2016-10-21 9:22 GMT+02:00 Elvis Stansvik <elvstone at gmail.com>:
> > Using
> >
> >     QApplication::desktop()->screenNumber(widget);
> >
> > it's possible to get the screen number of the screen where the widget
> > is mostly visible.
> >
> > But how can I be notified when this changes for a particular widget?
> >
>
> As a rough approximation, I tried connecting to QWindow::screenChanged
> of the window() for the widget, but it was never emitted when I moved
> the window between monitors.


In my experience, this is much trickier than it seems it should be.

Here is the relevant code from one of the classes in our application that
needs to be aware when it's moved from one display to another:

WMPixmapLabel::WMPixmapLabel(QWidget* parent) :
QLabel(parent),
_allowBitmapsOverride(false)
{
// NOTE: We do this as a single shot timer instead of immediately because
// depending on how this widget is created, its parentage up to a top level
// window may not be established.
QTimer::singleShot(0, this, SLOT(_connectToScreenChangedSignal()));
}

bool WMPixmapLabel::eventFilter(QObject *watched, QEvent *event)
{
if (event->type() == QEvent::WinIdChange) {
if (watched && window() == watched) {
_connectToScreenChangedSignal();
}
}
return false; // Don't filter out the event.
}

/**
\brief Connects to the top level window's screenChanged signal
and installs an event filter on the top level window so we can make
sure we're able to update our pixmap when necessary.
*/
void WMPixmapLabel::_connectToScreenChangedSignal()
{
// Disconnect any existing connections to the _updatePixmap slot.
disconnect(this, SLOT(_updatePixmap()));

// We do this for the side effect that will force this widget's top level
window
// to become a native window if it isn't already. It's required that the
window
// be a native window so that the call to windowHandle() below will return
non-null.
QWindow* theWindow = window()->windowHandle();
if (!theWindow) {
QWidget* winWidget = window();
if (winWidget) {
winWidget->winId();
theWindow = window()->windowHandle();
}
else {
// Should never get here.
Q_ASSERT(0);
}
}
Q_ASSERT(theWindow); // Should never fail.
if (theWindow) {
connect(theWindow, &QWindow::screenChanged, this,
&WMPixmapLabel::_updatePixmap, Qt::UniqueConnection);
installEventFilter(theWindow);
}

_updatePixmap();
}

Adam
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.qt-project.org/pipermail/interest/attachments/20161021/bfaf8c0a/attachment.html>


More information about the Interest mailing list