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

Elvis Stansvik elvstone at gmail.com
Fri Oct 21 17:50:07 CEST 2016


Thanks a lot for these snippets Adam, indeed a bit more work than I thought.

This is embarrassing, but since my first post I've realized I have no need
for being notified after all.

Anyway, it's good to see how it can be done, and might help someone else.

My use case was that I had a vtkRenderWindow (from VTK) on which I call
SetDPI(..) with the logical DPI detected my Qt. But I've now realized that
the logical DPI does not seem to change from screen to screen and
resolution to resolution. I somehow thought Qt programs would automatically
adjust text to be the same size when moved between screens, and therefore
wanted my VTK window to do the same to match. But seems they do not.

Elvis

Den 21 okt. 2016 2:57 em skrev "Adam Light" <aclight at gmail.com>:

>
>
> 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/9957d52a/attachment.html>


More information about the Interest mailing list